HTTP and SSH on the same port 443

My issue:
Trying to get both HTTP (with real client IP logging) and SSH working on the same port 443.

Solutions I’ve tried:
With ‘proxy_protocol on’, HTTP works and logs the real client IP which is what I want but SSH client fails to connected with error “ssh_dispatch_run_fatal: Connection to 10.0.0.30 port 443: message authentication code incorrect”. However, if I remove ‘proxy_protocol on’, HTTP fails but SSH works. What I need is for both HTTP and SSH to work on the same port and log the real client IP.

My config:

stream {
log_format stream_debug ‘[$time_local] Protocol: $ssl_preread_protocol, Upstream: $upstream, Client: $remote_addr, Status: $status’;
access_log /var/log/nginx/stream_access.log stream_debug;
error_log /var/log/nginx/stream_error.log debug;

# Connection limiting
limit_conn_zone $binary_remote_addr zone=addr:10m;

# Map SSL protocol to upstream
map $ssl_preread_protocol $upstream {
    "TLSv1.3" web;
    "TLSv1.2" web;
    "" ssh;
    default web;
}

upstream web {
    server 127.0.0.1:8443;
}

upstream ssh {
    server 172.17.0.1:22;
}

server {
    listen 443;
    ssl_preread on;
    proxy_pass $upstream;
    proxy_protocol on;
    limit_conn addr 10;
    proxy_connect_timeout 10s;
    proxy_timeout 300s;
}

}

http {
# Log format using proxy_protocol_addr for client IP
log_format main '$proxy_protocol_addr - $remote_user [$time_local] ’
'“$request” $status $body_bytes_sent “$http_referer” ’
‘“$http_user_agent”’;

server {
    listen 8443 ssl proxy_protocol;
    server_name 10.0.0.30;

    ssl_certificate /etc/nginx/ssl/signed.crt;
    ssl_certificate_key /etc/nginx/ssl/signed.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Set real IP from proxy_protocol
    set_real_ip_from 127.0.0.1;
    real_ip_header proxy_protocol;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;  # Now contains client IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass https://10.0.0.40;

        access_log /var/log/nginx/access.log main;
    }
}

}

The main issue is that when you enable proxy_protocol on in your stream server block, it’s sending the PROXY protocol header to both your HTTP and SSH upstream servers. While your HTTP server (NGINX on 8443) is configured to accept this with listen 8443 ssl proxy_protocol, your SSH server isn’t expecting the PROXY protocol header, causing the authentication error.