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!