I’m encountering an issue with my Nginx server related to external access on port 443. While everything seems to work fine when tested internally, I’m unable to access the server from external machines. Here’s a detailed overview of the problem and the steps I’ve taken:
Nginx Configuration:
server_name [my_domain].com www.[my_domain].com;
return 301 https://$host$request_uri;
server_name [my_domain].com www.[my_domain].com;
ssl_certificate /etc/letsencrypt/live/[my_domain].com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[my_domain].com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
proxy_pass http://localhost:8080;
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;
<code> server {
listen 80;
server_name [my_domain].com www.[my_domain].com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name [my_domain].com www.[my_domain].com;
ssl_certificate /etc/letsencrypt/live/[my_domain].com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[my_domain].com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://localhost:8080;
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;
}
}
</code>
server {
listen 80;
server_name [my_domain].com www.[my_domain].com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name [my_domain].com www.[my_domain].com;
ssl_certificate /etc/letsencrypt/live/[my_domain].com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[my_domain].com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://localhost:8080;
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;
}
}
Actions Taken:
-
Internal Access:
-
curl works correctly from the server itself.
-
telnet localhost 443 confirms that port 443 is listening.
-
The backend service running on port 8080 is confirmed to be
functioning properly.
External Access:
-
Verified that port 443 is open in the firewall (ufw), configured to
accept connections on both IPv4 and IPv6.
-
DNS configuration appears correct: dig [my_domain].com resolves to
the public IP [my_publicip] of my server.
-
Requests made to the public IP [my_publicip] on port 443 using HTTP
(not HTTPS) are successful, but HTTPS requests to [my_domain].com do
not work from external machines.
Logs and Errors:
- No evident errors in Nginx logs (/var/log/nginx/error.log), which
only show normal startup and shutdown process messages.
Connection Testing:
-
curl -v https://[my_domain].com works internally, but I am unable to
access the server from external machines.
-
SSL certificate validation has been confirmed, ensuring that the
certificates are correctly set up and valid.
Connection Testing:
Internal Test (from the server):
<code>curl -v https://[my_domain]/api/ping
<code>curl -v https://[my_domain]/api/ping
</code>
curl -v https://[my_domain]/api/ping
Output:
<code>* processing: https://[my_domain]/api/ping
* Trying [my_publicip]:443...
* Connected to [my_domain] ([my_publicip]) port 443
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted http/1.1
* subject: CN=[my_domain]
* start date: Aug 6 00:42:18 2024 GMT
* expire date: Nov 4 00:42:17 2024 GMT
* subjectAltName: host "[my_domain]" matched cert's "[my_domain]"
* issuer: C=US; O=Let's Encrypt; CN=E6
* SSL certificate verify ok.
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< Date: Tue, 06 Aug 2024 16:03:11 GMT
< Content-Type: application/json; charset=utf-8
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Content-Type, Authorization, Origin, Accept
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
* Connection #0 to host [my_domain] left intact
<code>* processing: https://[my_domain]/api/ping
* Trying [my_publicip]:443...
* Connected to [my_domain] ([my_publicip]) port 443
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted http/1.1
* Server certificate:
* subject: CN=[my_domain]
* start date: Aug 6 00:42:18 2024 GMT
* expire date: Nov 4 00:42:17 2024 GMT
* subjectAltName: host "[my_domain]" matched cert's "[my_domain]"
* issuer: C=US; O=Let's Encrypt; CN=E6
* SSL certificate verify ok.
* using HTTP/1.1
> GET /api/ping HTTP/1.1
> Host: [my_domain]
> User-Agent: curl/8.2.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 200 OK
< Server: nginx/1.26.1
< Date: Tue, 06 Aug 2024 16:03:11 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 18
< Connection: keep-alive
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Content-Type, Authorization, Origin, Accept
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
<
* Connection #0 to host [my_domain] left intact
{"message":"pong"}
</code>
* processing: https://[my_domain]/api/ping
* Trying [my_publicip]:443...
* Connected to [my_domain] ([my_publicip]) port 443
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted http/1.1
* Server certificate:
* subject: CN=[my_domain]
* start date: Aug 6 00:42:18 2024 GMT
* expire date: Nov 4 00:42:17 2024 GMT
* subjectAltName: host "[my_domain]" matched cert's "[my_domain]"
* issuer: C=US; O=Let's Encrypt; CN=E6
* SSL certificate verify ok.
* using HTTP/1.1
> GET /api/ping HTTP/1.1
> Host: [my_domain]
> User-Agent: curl/8.2.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 200 OK
< Server: nginx/1.26.1
< Date: Tue, 06 Aug 2024 16:03:11 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 18
< Connection: keep-alive
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Content-Type, Authorization, Origin, Accept
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
<
* Connection #0 to host [my_domain] left intact
{"message":"pong"}
External Test (from an external machine):
<code>curl -v https://[my_domain]/api/ping
<code>curl -v https://[my_domain]/api/ping
</code>
curl -v https://[my_domain]/api/ping
Output:
<code>* Trying [my_publicip]...
* Connected to [my_domain] ([my_publicip]) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
<code>* Trying [my_publicip]...
* TCP_NODELAY set
* Connected to [my_domain] ([my_publicip]) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
* Closing connection 0
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
</code>
* Trying [my_publicip]...
* TCP_NODELAY set
* Connected to [my_domain] ([my_publicip]) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
* Closing connection 0
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
Direct IP Test (from an external machine):
<code>curl -v http://[my_publicip]:443/api/ping
<code>curl -v http://[my_publicip]:443/api/ping
</code>
curl -v http://[my_publicip]:443/api/ping
Output:
<code>* Trying [my_publicip]...
* Connected to [my_publicip] ([my_publicip]) port 443 (#0)
> Host: [my_publicip]:443
> User-Agent: curl/7.64.1
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Content-Type, Authorization, Origin, Accept
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
< Content-Type: application/json; charset=utf-8
< Date: Tue, 06 Aug 2024 16:06:20 GMT
* Connection #0 to host [my_publicip] left intact
<code>* Trying [my_publicip]...
* TCP_NODELAY set
* Connected to [my_publicip] ([my_publicip]) port 443 (#0)
> GET /api/ping HTTP/1.1
> Host: [my_publicip]:443
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Content-Type, Authorization, Origin, Accept
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
< Content-Type: application/json; charset=utf-8
< Date: Tue, 06 Aug 2024 16:06:20 GMT
< Content-Length: 18
<
* Connection #0 to host [my_publicip] left intact
{"message":"pong"}
</code>
* Trying [my_publicip]...
* TCP_NODELAY set
* Connected to [my_publicip] ([my_publicip]) port 443 (#0)
> GET /api/ping HTTP/1.1
> Host: [my_publicip]:443
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Content-Type, Authorization, Origin, Accept
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Origin: *
< Content-Type: application/json; charset=utf-8
< Date: Tue, 06 Aug 2024 16:06:20 GMT
< Content-Length: 18
<
* Connection #0 to host [my_publicip] left intact
{"message":"pong"}
Questions:
- What could be causing the server Nginx to be inaccessible externally,
despite functioning well internally?
- Could there be any issues with the Nginx configuration or the
server’s network setup?
- Are there any additional checks or configurations that might resolve
this issue?
Additional Information:
-
The server is hosted on a DigitalOcean droplet.
-
Both internal and external dig queries resolve [my_domain].com to the
public IP [my_publicip].
-
When I refer to “internal,” I mean that I am executing commands directly from the server’s local console. On the other hand, when I refer to “external,” I mean using clients such as Postman, Chrome, or even the terminal on my personal computer to perform operations.
Any insights or suggestions would be greatly appreciated. Thank you!