Merge pull request #2 from MatthewL246/separate-containers

This commit is contained in:
Jonathan Barrow 2024-06-05 09:42:04 -04:00 committed by GitHub
commit b458efe3e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 241 additions and 133 deletions

7
.gitignore vendored
View File

@ -130,7 +130,6 @@ dist
.pnp.*
# custom
dist
docker/*.pem
docker/*.key
docker/nginx.conf
nginx/nginx.conf
nginx/*.pem
nginx/*.key

View File

@ -1,83 +0,0 @@
# syntax=docker/dockerfile:1
ARG openssl_version="1.1.1w"
ARG openssl_dir="/usr/local/ssl"
ARG nginx_version="1.24.0"
ARG nginx_dir="/opt/nginx"
# * Use Ubuntu 18.04 as the build image as it's known-good for TLS 1.0/1.1
FROM ubuntu:18.04 AS build
# * Install build dependencies
RUN apt-get update
RUN apt-get install -y \
curl \
build-essential \
libffi-dev \
pkg-config \
libssl-dev \
libpcre3 \
libpcre3-dev \
zlib1g-dev
# * Download and compile old OpenSSL
ARG openssl_version openssl_dir
RUN curl -fSL https://www.openssl.org/source/openssl-${openssl_version}.tar.gz | tar xz -C /tmp/
WORKDIR /tmp/openssl-${openssl_version}
RUN ./config --prefix=${openssl_dir} --openssldir=${openssl_dir} -Wl,-Bsymbolic-functions -fPIC shared
RUN make -j$(nproc)
RUN make install_sw
# * Download and compile old nginx with custom OpenSSL
ARG nginx_version nginx_dir
RUN curl -fSL http://nginx.org/download/nginx-${nginx_version}.tar.gz | tar xz -C /tmp/
WORKDIR /tmp/nginx-${nginx_version}
RUN ./configure \
--prefix=${nginx_dir} \
--with-http_ssl_module \
--with-openssl=/tmp/openssl-${openssl_version} \
--with-openssl-opt="enable-weak-ssl-ciphers" \
--with-pcre
RUN make -j$(nproc)
RUN make install
# * Use Ubuntu as we need to install several pieces of software
FROM ubuntu:latest
# * Create required directories
RUN mkdir /app
RUN mkdir -p /etc/nginx/ssl
RUN mkdir -p /var/log/nginx
# * Move the nginx and OpenSSL to the container
ARG openssl_dir nginx_dir
COPY --from=build ${openssl_dir} ${openssl_dir}
COPY --from=build ${nginx_dir} ${nginx_dir}
# * Set PATH to include custom OpenSSL and nginx
ENV PATH="${nginx_dir}/sbin:${PATH}"
ENV LD_LIBRARY_PATH="${openssl_dir}/lib:${LD_LIBRARY_PATH}"
# * Install NodeJS and PM2
RUN apt-get update && apt-get install -y curl software-properties-common
RUN curl -fsSL https://deb.nodesource.com/setup_current.x | bash -
RUN apt-get install -y nodejs
RUN npm install -g pm2
# * Copy the built DNS server
COPY dist /app/dist
COPY package.json /app
COPY .env /app
# * Copy the nginx files
COPY docker/nginx.conf /opt/nginx/conf/nginx.conf
COPY docker/ca.pem /etc/nginx/ssl/ca.pem
COPY docker/private.key /etc/nginx/ssl/private.key
# * nginx ports
EXPOSE 80 443
# * Start nginx and DNS server at boot
WORKDIR /app
RUN npm i
CMD nginx -g 'daemon off;' & pm2 start . --no-daemon

View File

@ -1,38 +1,14 @@
# SSSL DNS
Custom DNS server intended to be used in conjunction with [SSSL](https://github.com/PretendoNetwork/SSSL). Redirects Nintendo hostnames to an SSSL powered server.
## Config
The only 2 addresses required are for `conntest.nintendowifi.net` and `account.nintendo.net`. These can either be set using the default address or explicitly mapping them. Additional addresses may be added using `SSSL_DNS_MAP`.
This project contains a DNS server and a custom Nginx configuration intended to be used in conjunction with [SSSL](https://github.com/PretendoNetwork/SSSL).
| Name | Description | Required |
|----------------------------|----------------------------------------------------------------------------------------|----------------------------------------|
| `SSSL_UDP_PORT` | UDP port for the DNS server. | Only if not using TCP. |
| `SSSL_TCP_PORT` | TPC port for the DNS server. | Only if not using UDP. |
| `SSSL_DNS_DEFAULT_ADDRESS` | The default address to use for `conntest.nintendowifi.net` and `account.nintendo.net`. | Only if not explicitly mapped. |
| `SSSL_DNS_MAP_hostname` | An explicit mapping of a hostname to an address. | Only if not using the default address. |
## Usage
### Example:
The provided [example Docker Compose file](./compose.yml) shows a setup that runs both the DNS server and Nginx together. Here's how to set it up:
```
# Listen on port 5335
SSSL_UDP_PORT=5335
# Use the default address for conntest.nintendowifi.net and account.nintendo.net
SSSL_DNS_DEFAULT_ADDRESS=127.0.0.1
# Explicitly mapping addresses
SSSL_DNS_MAP_conntest.nintendowifi.net=127.0.0.1
SSSL_DNS_MAP_account.nintendo.net=127.0.0.1
SSSL_DNS_MAP_discovery.olv.nintendo.net=127.0.0.1
```
## Docker
The provided `Dockerfile` creates an image which runs both the DNS server and a custom build of nginx with TLS 1.0/1.1, and legacy SSL ciphers, enabled, as these are required for the Wii U. To build the image:
1. Use [SSSL](https://github.com/PretendoNetwork/SSSL) to create your patched SSL certficiates.
2. Copy the `ssl-cert-private-key.pem` from SSSL file to `docker/private.key` (or modify the private key name in step 4) in SSSL-DNS.
3. Copy the `cert-chain.pem` from SSSL file to `docker/ca.pem` (or modify the certificate chain name in step 4) in SSSL-DNS.
4. Create `docker/nginx.conf` from `docker/nginx.example.conf` and modify it to your liking. This will be used as the nginx default configuration, *not* a separate site config. Add any additional hostnames you may need.
5. Create a `.env` file in the same directory as the `Dockerfile` following the above guide.
6. `docker build -t IMAGE_NAME .`
7. Create a container with the image, exposing ports 80, 443 and the DNS server port (by default the Wii U only supports the default port 53)
1. Clone this repository: `git clone https://github.com/PretendoNetwork/SSSL-DNS.git`.
2. Use [SSSL](https://github.com/PretendoNetwork/SSSL) to create your own patched SSL certficiates.
3. Copy the `cert-chain.pem` and `ssl-cert-private-key.pem` from SSSL to the `nginx` directory in this repository.
4. Create an Nginx configuration file `nginx.conf` in the `nginx` directory. Check the [Nginx configuration README](./nginx/README.md) for more information.
5. Create a `.env` file in the `dns` directory. Check the [DNS server README](./dns/README.md) for more information.
6. Run `docker-compose up -d --build` to build and start your SSSL environment. This will take some time the first time you run it but will be faster on subsequent runs.

21
compose.yml Normal file
View File

@ -0,0 +1,21 @@
# Example of a Docker Compose file that runs the DNS and Nginx containers together
services:
dns:
build: ./dns
restart: always
ports:
- 53:53/udp
env_file:
- ./dns/.env
nginx:
build: ./nginx
restart: always
ports:
- 80:80
- 443:443
volumes:
- ./nginx/cert-chain.pem:/opt/nginx/ssl/ca.pem:ro
- ./nginx/ssl-cert-private-key.pem:/opt/nginx/ssl/private.key:ro
- ./nginx/nginx.conf:/opt/nginx/conf/nginx.conf:ro

3
dns/.dockerignore Normal file
View File

@ -0,0 +1,3 @@
.env
node_modules
dist

View File

@ -1,2 +1,2 @@
dist
*.js
*.js

View File

@ -51,4 +51,4 @@
"always"
]
}
}
}

45
dns/Dockerfile Normal file
View File

@ -0,0 +1,45 @@
# syntax=docker/dockerfile:1
ARG app_dir="/home/node/app"
# * Base Node.js image
FROM node:20-alpine AS base
ARG app_dir
WORKDIR ${app_dir}
# * Installing production dependencies
FROM base AS dependencies
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci --omit=dev
# * Installing development dependencies and building the application
FROM base AS build
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci
COPY . .
RUN npm run build
# * Running the final application
FROM base AS final
ARG app_dir
ENV NODE_ENV production
USER node
COPY package.json .
COPY --from=dependencies ${app_dir}/node_modules ${app_dir}/node_modules
COPY --from=build ${app_dir}/dist ${app_dir}/dist
CMD ["node", "."]

20
dns/README.md Normal file
View File

@ -0,0 +1,20 @@
# SSSL DNS server
Custom DNS server intended to be used in conjunction with [SSSL](https://github.com/PretendoNetwork/SSSL). It redirects Nintendo hostnames to an SSSL-powered server using DNS spoofing.
## Config
The only 2 addresses required are for `conntest.nintendowifi.net` and `account.nintendo.net`. These can either be set using the default address or explicitly mapping them. Additional addresses may be added using `SSSL_DNS_MAP`.
| Name | Description | Required |
| -------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------- |
| `SSSL_UDP_PORT` | UDP port for the DNS server. | Only if not using TCP. |
| `SSSL_TCP_PORT` | TPC port for the DNS server. | Only if not using UDP. |
| `SSSL_DNS_DEFAULT_ADDRESS` | The default address to use for `conntest.nintendowifi.net` and `account.nintendo.net`. | Only if not explicitly mapped. |
| `SSSL_DNS_MAP_hostname` | An explicit mapping of a hostname to an address. | Only if not using the default address. |
These environment variables can be set manually or loaded from a `.env` file. See [example.env](./example.env) for an example configuration.
## Docker
The provided `Dockerfile` creates an image that runs the DNS server with Node.js. The configuration environment variables should either be provided to the container directly or mounted as a `.env` file in `/home/node/app/.env`. The [example Docker Compose file](../compose.yml) shows a setup that loads the configuration from a `.env` file in this directory.

10
dns/example.env Normal file
View File

@ -0,0 +1,10 @@
# Listen on port 53 (please note that the Wii U does not support custom DNS ports)
SSSL_UDP_PORT=53
# Use the default address for conntest.nintendowifi.net and account.nintendo.net
SSSL_DNS_DEFAULT_ADDRESS=127.0.0.1
# Explicitly mapping addresses
SSSL_DNS_MAP_conntest.nintendowifi.net=127.0.0.1
SSSL_DNS_MAP_account.nintendo.net=127.0.0.1
SSSL_DNS_MAP_discovery.olv.nintendo.net=127.0.0.1

View File

@ -1,12 +1,12 @@
{
"name": "@pretendonetwork/sssl-dns",
"version": "1.0.1",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@pretendonetwork/sssl-dns",
"version": "1.0.1",
"version": "1.0.0",
"license": "AGPL-3.0",
"dependencies": {
"@colors/colors": "^1.6.0",

View File

@ -5,9 +5,8 @@
"main": "dist/server.js",
"scripts": {
"lint": "npx eslint .",
"build": "npm run lint && npm run clean && npx tsc && npx tsc-alias && npm run copy-files",
"build": "npm run lint && npm run clean && npx tsc && npx tsc-alias",
"clean": "npx rimraf ./dist",
"copy-files": "cp package.json dist/package.json && cp README.md dist/README.md",
"start": "node --enable-source-maps ."
},
"author": "PretendoNetwork",

View File

@ -3,6 +3,10 @@ import { table } from 'table';
import colors from '@colors/colors';
import dotenv from 'dotenv';
process.on('SIGTERM', () => {
process.exit();
});
dotenv.config();
const addressMap: Record<string, string> = {};
@ -144,4 +148,4 @@ server.on('listening', () => {
server.listen({
udp: udpPort !== 0 ? udpPort : undefined,
tcp: tcpPort !== 0 ? tcpPort : undefined
});
});

View File

@ -18,4 +18,4 @@
}
},
"include": ["src"]
}
}

56
nginx/Dockerfile Normal file
View File

@ -0,0 +1,56 @@
# syntax=docker/dockerfile:1
ARG openssl_version="1.1.1w"
ARG nginx_version="1.24.0"
ARG nginx_dir="/opt/nginx"
FROM ubuntu:24.04 AS build
# * Install build dependencies
RUN apt-get update \
&& apt-get install -y \
curl \
build-essential \
pkg-config \
zlib1g-dev \
&& apt-get clean
# * Download old OpenSSL
ARG openssl_version
RUN curl -fSL https://www.openssl.org/source/openssl-${openssl_version}.tar.gz | tar xz -C /tmp/
# * Download and compile old nginx with custom OpenSSL
ARG nginx_version nginx_dir
RUN curl -fSL http://nginx.org/download/nginx-${nginx_version}.tar.gz | tar xz -C /tmp/
WORKDIR /tmp/nginx-${nginx_version}
RUN ./configure \
--prefix=${nginx_dir} \
--with-http_ssl_module \
--with-openssl=/tmp/openssl-${openssl_version} \
--with-openssl-opt="enable-weak-ssl-ciphers" \
--without-http_rewrite_module
RUN make -j$(nproc)
RUN make install
FROM ubuntu:24.04 AS final
# * Create required directories
RUN mkdir -p /var/log/nginx
# * Move the nginx and OpenSSL to the container
ARG nginx_dir
COPY --from=build ${nginx_dir} ${nginx_dir}
# * Set PATH to include custom nginx
ENV PATH="${nginx_dir}/sbin:${PATH}"
# * Copy the default nginx configuration
COPY nginx.default.conf /opt/nginx/conf/nginx.conf
# * nginx ports
EXPOSE 80 443
# * Start nginx
CMD ["nginx", "-g", "daemon off;"]

16
nginx/README.md Normal file
View File

@ -0,0 +1,16 @@
# SSSL Nginx configuration
Nginx configuration intended to be used in conjunction with [SSSL](https://github.com/PretendoNetwork/SSSL). It supports TLS 1.0/1.1 and legacy SSL ciphers, which are required for the Wii U.
## Configuration
This uses standard Nginx configuration files. Use these two example files as a starting point:
- `nginx.default.conf` is a simple Nginx configuration file that displays the default Nginx welcome page. It shows the basic configuration needed to create a server that uses an SSSL-patched certificate and supports the necessary legacy SSL ciphers.
- `nginx.example.conf` is an example Nginx configuration file that shows how to reverse-proxy incoming requests to a local Pretendo account server.
## Docker
The provided `Dockerfile` creates an image that compiles custom versions of OpenSSL and Nginx with support for TLS 1.0/1.1 and legacy SSL ciphers. Nginx is installed to `/opt/nginx`, so a custom configuration file should be mounted into the container at `/opt/nginx/conf/nginx.conf` as shown in the [example Docker Compose file](../compose.yml).
The default configuration requires an SSSL certificate to run. The `cert-chain.pem` and `ssl-cert-private-key.pem` files generated by [SSSL](https://github.com/PretendoNetwork/SSSL) should be mounted into the container at `/opt/nginx/ssl/` as `ca.pem` and `private.key` respectively, as shown in the [example Docker Compose file](../compose.yml).

40
nginx/nginx.default.conf Normal file
View File

@ -0,0 +1,40 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
error_log /dev/stderr;
error_log /var/log/nginx/error.log;
access_log /dev/stdout;
access_log /var/log/nginx/access.log;
# A basic default configuration using the SSSL certificate
server {
listen 80 default_server;
listen 443 ssl default_server;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
ssl_protocols TLSv1 TLSv1.1;
ssl_ciphers ALL;
ssl_prefer_server_ciphers on;
ssl_certificate /opt/nginx/ssl/ca.pem;
ssl_certificate_key /opt/nginx/ssl/private.key;
}
}

View File

@ -5,13 +5,15 @@ events {
}
http {
include mime.types;
include mime.types;
default_type application/octet-stream;
sendfile on;
sendfile on;
keepalive_timeout 65;
error_log /dev/stderr;
error_log /var/log/nginx/error.log;
access_log /dev/stdout;
access_log /var/log/nginx/access.log;
server {
@ -47,7 +49,7 @@ http {
ssl_protocols TLSv1 TLSv1.1;
ssl_ciphers ALL;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/nginx/ssl/ca.pem;
ssl_certificate_key /etc/nginx/ssl/private.key;
ssl_certificate /opt/nginx/ssl/ca.pem;
ssl_certificate_key /opt/nginx/ssl/private.key;
}
}
}