barronwaffles / dwc_network_server_emulator

A Nintendo DS and Wii server emulator.
GNU Affero General Public License v3.0
1.07k stars 166 forks source link

Need help setting op a local server using SSL #565

Open CasparNuel opened 11 months ago

CasparNuel commented 11 months ago

Hello,

I am trying to get this setup working with a locally hosted Raspberry Pi and a copy of this dwc_network_server_emulator codebase.

The caveat being that I need to use nds-constraint as I am trying to use this setup with an unmodded retail cartridge (so no ssl patch!!!) on my Nintendo DSi.

I have successfully followed the nds-constraint steps to create a proper SSL certificate (i believe - is there a way to check?).

I have compiled an old version of Openssl (1.0.2k) and have built Nginx on top of this using the flags enable-ssl2, enable-ssl3, enable-ssl3-method and enable-weak-ssl-ciphers.

Currently, I believe to be really close to getting this to work.

This is a record of a handshake with the actual nintendo wfc service:

image

As you can see, after a few empty TCP acknowledgements, there is a Client Key exchange. I fail to achieve this client key exchange and would like some help with figuring out why this is not working currently.

Here is a screenshot of my latest attempt, with my own instance of dwc_network_server_emulator, using Nginx and nds-constraint, hosted locally:

image

10.42.0.24 is my Nintendo DSi in this case. As you can see, after the few empty TCP packets, no Client Key Exchange is performed and my console gets an errocode 20100.

Could anyone help me finalize this setup? Thanks very much for any input on this issue.

PS: The DWC server does get the initial game request, but no further communication happens (most likely due to the failing SSL handshake)

image

Luporion commented 7 months ago

Did you ever manage to get the SSL handshake working? It would be really useful to have a working dwc server without having to patch every ISO or console to not use SSL. A working SSL handshake would make everything much easier for setting up events

CasparNuel commented 7 months ago

@Luporion Yes I did! It was a hassle though and it has been a while, but I needed to compile nginx (proxy server) with a very outdated version of OpenSSL installed.

The reason the SSL handshake failed in the setup I described here is that more recent OpenSSL versions no longer support the weak algorithms used by the DS to communicate.

If you're interested I could see if I can find the build logs for my test setup I made a while back but that could take some time.

Edit: I don't recall exactly of the top of my head, but in the end I had to use an even older OpenSSL version than the one I described above.

CasparNuel commented 7 months ago

@Luporion Yes I did! It was a hassle though and it has been a while, but I needed to compile nginx (proxy server) with a very outdated version of OpenSSL installed.

The reason the SSL handshake failed in the setup I described here is that more recent OpenSSL version no longer support the weak algorithms used by the DS to communicate.

If you're interested I could see if I can find the build logs for my test setup I made a while back but that could take some time.

Edit:

Went through my notes, seems that I used OpenSSL 1.0.2K and built nginx 1.18.1 using that openssl version.

During the build, enable-ssl2, enable-ssl3 was used.

I'll see if I can get some more info but I think this is enough to get it working (and a correclty built nds-constraint cert ofcourse).

Luporion commented 7 months ago

Nice to hear. I'm trying to figure out how to create the least complicated way of having a lanparty, without my friends having to know computer science.

Using the No-SSL-Gecko code works and isn't really complicated, but being able to skip that part would really ease some troubleshooting headaches. Unfortunately i'm far from being a pro programmer, thats why i've looked into pretty much every fork of DWC, CoWFC, and some docker containers looking for related issues

CasparNuel commented 7 months ago

Nice to hear. I'm trying to figure out how to create the least complicated way of having a lanparty, without my friends having to know computer science.

Using the No-SSL-Gecko code works and isn't really complicated, but being able to skip that part would really ease some troubleshooting headaches. Unfortunately i'm far from being a pro programmer, thats why i've looked into pretty much every fork of DWC, CoWFC, and some docker containers looking for related issues

I'm at my pc now, so replying should be a bit easier :smile:

The Nginx version my setup eventually worked with is this one (I see now it is a newer version than I texted here before - sorry about that, I misremembered it):

nginx version: nginx/1.20.2
built by gcc 12.1.0 (GCC)
built with OpenSSL 1.0.2k  26 Jan 2017
TLS SNI support enabled
configure arguments: --with-http_ssl_module --with-openssl=/home/xyz/Development/openssl/openssl-1.0.2k --with-openssl-opt=enable-ssl2 --with-openssl-opt=enable-ssl3 --with-openssl-opt=enable-ssl3-method --with-openssl-opt=enable-weak-ssl-ciphers

As stated before, the openSSL version compiled and used for the build is OpenSSL-1.0.2K.

The config file I use with this nginx version is as follows:

user http;
worker_processes auto;
worker_cpu_affinity auto;

events {
    multi_accept on;
    worker_connections 1024;
}

http {
    charset utf-8;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    server_tokens off;
    log_not_found off;
    types_hash_max_size 4096;
    client_max_body_size 16M;

    # MIME
    include mime.types;
    default_type application/octet-stream;

    # logging
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log warn;

    # load configs
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    # Hardcoded Nintendo DS server
    server {
    listen       80;
    server_name  conntest.nintendowifi.net;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
        root   /usr/local/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/local/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

server {
    listen 443 ssl;
    server_name nas.nintendowifi.net;

    #####
    # ADDED FOR DS COMPATABILITY
    ssl_protocols SSLv2 SSLv3;
    ssl_ciphers ALL;
    underscores_in_headers on;
    proxy_pass_request_headers on;
    #####

    ssl_certificate /usr/local/nginx/ssl/server-chain.crt;
    ssl_certificate_key /usr/local/nginx/ssl/server.key;

    location / {
        proxy_pass http://127.0.0.1:9000;
        #proxy_set_header Host $host;
        #proxy_set_header X-Real-IP $remote_addr;
        #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #proxy_set_header X-Forwarded-Proto $scheme;

        #proxy_http_version 1.1;
        #proxy_set_header Upgrade $http_upgrade;
        #proxy_set_header Connection "upgrade";
    }
}

}

Excuse the somewhat messy commenting of options, when I got this to work I was about 3 days into re-compiling nginx/openssl over and over and was no longer really trying to keep it all tidy.

Things of note here are obviously the lines marked with ADDED FOR DS and also that I had to create a server-chain certificate (basically your created nds-constraint cert and the root cert used to create it appended to eachother, a quick google should help you with how to make this, I don't have the command at hand anymore)

Furthermore also the correct nintendo domain names should be used, and your dns should resolve them to your local mocks and not the actual nintendo domains.

That's all I can think of right now that should help you. If you still can't get it to work, you can ask here and I'll see if I can help.

The biggest struggle for me was finding the correct openssl/nginx versions and getting them compiled with the right flags. The rest should be somewhat straightforward to setup once you have the correct openssl/nginx versions installed and configured.