How to Setup a Secure Quake III Game Server Which One Can Play On in Your Browser
In this article, you will learn how to quickly setup a secure Quake III server and client. The emphasis here is on secure i.e. this can be done with https. I wrote another article for setting up the server and client where the connection is also secure but where the costs for running it are even cheaper since it does not rely on a Load Balancer.
Quake III, the legendary first-person shooter from 1999, continues to captivate gamers worldwide. Its open-source release in 2005 sparked various enhancements, and among them is QuakeKube. This adaptation harnesses Kubernetes, allowing players to relive Quake III's action-packed arenas right from their browsers. The creators of QuakeKube have packaged everything you need to play in a Kubernetes cluster, making the setup process straightforward.
A little detour on the technical part. QuakeKube basically runs a dedicated quake server from the ioquake3 project which has been written in C and C++ which communicates with the Java Script web client (taken from QuakeJS) via a proxy. This works smoother than the QuakeJS server because it runs in its original programming language. It also allows both browser-based and real-client gaming. I will create another article in the future to explain how both, browser and real-client users can join the same game. Besides QuakeJS, there exist other ports to run the game in the browser like e.g. ioquake3.js, Quake3 and planet_quake.
Prerequisites:
- My previous article: Integrating DigitalOcean Cloud Controller with k0s in Your Kubernetes Cluster: A Guide
- A DigitalOcean account and API token. If you use my referral link and spend more than 25$ on DigitalOcean, I will receive 25$.
- A droplet configured on DigitalOcean. I recommend Ubuntu.
- Access to the droplet via DigitalOcean console or SSH.
- Domain name pointing to the Load Balancer of the DigitalOcean droplet.
- Swap file with 4GB and swappiness of 60
Step-by-Step Guide:
1. Connect to Your Droplet
Option 1: SSH
Use SSH to access your DigitalOcean droplet:
ssh -i /path/to/your/private/key root@<droplet-ip-address>
Replace /path/to/your/private/key with your private key file path and <droplet-ip-address> with your droplet's IP.
Option 2: DigitalOcean Console
Alternatively, utilize the built-in console by DigitalOcean. Head to the “Droplets” section in your DigitalOcean dashboard, select the droplet you wish to access, and click on “Console”.
2. Install cert-manager
Cert-manager is a Kubernetes add-on to automate the management and issuance of TLS certificates from various issuing sources. We'll use it to secure our Quake server. Install cert-manager by running:
k0s kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
3. Deploy the Quake Server
Use the following manifest to deploy the Quake servers. This manifest should be in a YAML
file. You can create this file by typing nano quake-manifest.yaml
and
copying and pasting the manifest into the file. Please note, that it is essential to
change all the passwords provided in the Quake III Arena server configuration files to
ensure security. Close and save with CTRL and X, confirming with a Y.
apiVersion: apps/v1 kind: Deployment metadata: name: quake spec: selector: matchLabels: run: quake replicas: 1 template: metadata: labels: run: quake annotations: prometheus.io/scrape: 'true' prometheus.io/port: '8080' spec: containers: - command: - q3 - server - --config=/config/config.yaml - --content-server=http://127.0.0.1:9090 - --agree-eula image: docker.io/criticalstack/quake:latest name: server ports: - containerPort: 8080 readinessProbe: tcpSocket: port: 8080 initialDelaySeconds: 15 periodSeconds: 5 volumeMounts: - name: quake3-server-config mountPath: /config - name: quake3-content mountPath: /assets - command: - q3 - content - --seed-content-url=http://content.quakejs.com image: docker.io/criticalstack/quake:latest name: content-server ports: - containerPort: 9090 volumeMounts: - name: quake3-content mountPath: /assets volumes: - name: quake3-server-config configMap: name: quake3-server-config - name: quake3-content emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: quake spec: type: NodePort selector: run: quake ports: - port: 8080 targetPort: 8080 nodePort: 30001 name: client - port: 27960 targetPort: 27960 nodePort: 30003 name: server protocol: UDP - port: 9090 targetPort: 9090 nodePort: 30002 name: content --- apiVersion: v1 kind: ConfigMap metadata: name: quake3-server-config data: config.yaml: | fragLimit: 25 timeLimit: 15m bot: minPlayers: 3 game: motd: "Welcome" type: FreeForAll forceRespawn: false inactivity: 10m quadFactor: 3 weaponRespawn: 3 password: Ei&Y2WvF4N server: hostname: "quakekube" maxClients: 20 password: 4s%qj0iHEs commands: - addbot sarge 2 maps: - name: q3dm7 type: FreeForAll timeLimit: 10m - name: q3dm17 type: FreeForAll - name: q3wctf1 type: CaptureTheFlag captureLimit: 8 - name: q3tourney2 type: FreeForAll - name: q3wctf3 type: CaptureTheFlag captureLimit: 8 - name: ztn3tourney1 type: FreeForAll
Once you've copied the manifest into a file, you can deploy it with kubectl apply
-f
quake-manifest.yaml
.
4. Setup Let's Encrypt for TLS
We'll use Let's Encrypt to secure our Quake servers with TLS.
Use the following manifest to set up Let's Encrypt. This manifest should also be in a
YAML file like we have done before nano cluster-issuer.yaml
and then
execute it with k0s kubectl apply -f cluster-issuer.yaml
. Please change the
email to your email address.
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: email: youremail.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx
5. Setup Ingress
The Ingress basically redirects the traffic to the service and finally to the pod. Copy
the manifest, put it in a file nano ingress.yaml
and execute it with
k0s kubectl apply -f ingress.yaml
. Please change the host to your domain
name and remember to update your DNS record to point to the Load Balancer.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: quake-ingress annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/ssl-redirect: "true" spec: ingressClassName: nginx rules: - host: yourwebsite.com http: paths: - pathType: Prefix path: "/" backend: service: name: quake port: number: 8080 tls: - secretName: quake-tls hosts: - yourwebsite.com
Verification:
To verify that everything is working correctly, use k0s kubectl get pods
to
check that all the pods are running. Also, check the logs of the Quake server pods to
ensure they are functioning correctly. This is done via the following command:
k0s kubectl logs pod-name
or
k0s kubectl logs -f podname
You get the podname via k0s kubectl get pods
.
Wrapping Up:
Congratulations! You've set up a Quake server on a single-node Kubernetes cluster on a DigitalOcean droplet using k0s. Now you can enjoy playing Quake with your friends, hosted on your very own server! Remember, Kubernetes is a powerful tool, and this is just the beginning. The more you play around with it, the more you'll uncover its potential. Happy gaming and exploring!