When running Jenkins behind Nginx with authentication handled by the reverse proxy, it's crucial to prevent direct external access to Jenkins' default port (typically 8080). The current setup exposes a security vulnerability where users can bypass Nginx authentication by connecting directly to port 8080.
The most effective solution is to modify Jenkins' HTTP connector to only listen on localhost. This can be done through Jenkins' configuration files:
# For systemd installations (modern Linux distributions)
sudo systemctl edit jenkins
[Service]
Environment="JENKINS_LISTEN_ADDRESS=127.0.0.1"
For older init.d systems, edit the init configuration:
# Edit the Jenkins startup parameters
sudo nano /etc/default/jenkins
# Add or modify this line:
JENKINS_ARGS="--httpListenAddress=127.0.0.1"
If you prefer configuring through the Jenkins XML config file:
sudo nano /var/lib/jenkins/config.xml
<service>
<connector name="http" class="org.eclipse.jetty.server.bio.SocketConnector">
<port>8080</port>
<host>127.0.0.1</host>
...
</connector>
</service>
As an additional security measure, consider implementing firewall rules to block external access to port 8080:
# Using iptables
sudo iptables -A INPUT -p tcp --dport 8080 -j DROP
sudo iptables -A INPUT -p tcp -s 127.0.0.1 --dport 8080 -j ACCEPT
# For UFW (Ubuntu)
sudo ufw deny 8080
sudo ufw allow from 127.0.0.1 to any port 8080
After making changes, restart Jenkins and verify the listening ports:
sudo systemctl restart jenkins
sudo netstat -tulpn | grep 8080
# Correct output should show:
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN
Ensure your Nginx configuration properly proxies to Jenkins on localhost:
location / {
proxy_pass http://127.0.0.1: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;
# Add your authentication configuration here
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
}
When running Jenkins behind Nginx as a reverse proxy, many administrators don't realize that Jenkins continues to expose its native port (typically 8080) to external networks. This creates a serious security vulnerability where users can bypass your Nginx authentication layer by accessing Jenkins directly.
Jenkins has multiple configuration points that control network binding:
1. The JENKINS_ARGS in init scripts
2. The --httpListenAddress parameter
3. XML configuration files in /etc/default/jenkins
For modern Jenkins installations (2.0+), modify your startup configuration:
# Edit /etc/default/jenkins
JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpPort=8080 --httpListenAddress=127.0.0.1"
For systemd systems (most modern Linux):
# Create/edit /etc/systemd/system/jenkins.service.d/override.conf
[Service]
Environment="JENKINS_OPTS=--httpListenAddress=127.0.0.1"
After making changes, verify Jenkins is only bound to localhost:
sudo netstat -tulpn | grep 8080
# Should show:
tcp6 0 0 127.0.0.1:8080 :::* LISTEN PID/jenkins
Here's a complete Nginx proxy setup that works with this localhost binding:
server {
listen 443 ssl;
server_name jenkins.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1: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;
# Required for websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Consider implementing these complementary security controls:
- Firewall rules to block external access to port 8080
- Network-level restrictions using security groups (AWS) or NSGs (Azure)
- Set up fail2ban to protect against brute force attacks