Secure your Nexus Repository Manager with SSL/TLS certificates, enforce HTTPS connections, and implement comprehensive security hardening including authentication controls, access policies, and audit logging for production environments.
Prerequisites
- Nexus Repository Manager installed
- Root or sudo access
- Domain name configured
- Basic understanding of SSL/TLS
What this solves
This tutorial configures SSL certificates for encrypted HTTPS connections to Nexus Repository Manager and implements security hardening measures to protect your artifact repositories in production. You'll enable TLS encryption, configure security headers, set up proper authentication controls, and establish audit logging for compliance requirements.
Step-by-step configuration
Update system and install SSL tools
Start by updating your system and installing the necessary SSL certificate tools for managing TLS certificates.
sudo apt update && sudo apt upgrade -y
sudo apt install -y openssl certbot nginxStop Nexus Repository Manager
Stop Nexus temporarily to modify its configuration files safely without service conflicts.
sudo systemctl stop nexus
sudo systemctl status nexusGenerate SSL certificate
Create an SSL certificate using Let's Encrypt for automatic renewal or generate a self-signed certificate for internal use.
# For Let's Encrypt (replace example.com with your domain)
sudo certbot certonly --standalone -d nexus.example.com
OR for self-signed certificate (internal use)
sudo mkdir -p /opt/sonatype-work/nexus3/etc/ssl
sudo openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
-subj "/C=US/ST=State/L=City/O=Organization/CN=nexus.example.com" \
-keyout /opt/sonatype-work/nexus3/etc/ssl/nexus.key \
-out /opt/sonatype-work/nexus3/etc/ssl/nexus.crtConfigure Java keystore
Convert the SSL certificate to Java keystore format that Nexus can use for HTTPS connections.
# Create PKCS12 keystore from certificate
sudo openssl pkcs12 -export -in /etc/letsencrypt/live/nexus.example.com/fullchain.pem \
-inkey /etc/letsencrypt/live/nexus.example.com/privkey.pem \
-out /opt/sonatype-work/nexus3/etc/ssl/nexus.p12 \
-name nexus -passout pass:nexusssl123
Convert to Java keystore
sudo keytool -importkeystore \
-deststorepass nexusssl123 \
-destkeypass nexusssl123 \
-destkeystore /opt/sonatype-work/nexus3/etc/ssl/keystore.jks \
-srckeystore /opt/sonatype-work/nexus3/etc/ssl/nexus.p12 \
-srcstoretype PKCS12 \
-srcstorepass nexusssl123 \
-alias nexusConfigure Nexus SSL properties
Update Nexus configuration to enable HTTPS with the SSL certificate and security settings.
# HTTP and HTTPS configuration
nexus.scripts.allowCreation=false
nexus.security.randompassword=false
SSL/TLS configuration
application-port-ssl=8443
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-https.xml,${jetty.etc}/jetty-requestlog.xml
ssl.etc=${karaf.data}/etc/ssl
Security hardening
nexus.security.anticsrf.enabled=true
nexus.security.anticsrf.cookieMaxAge=1800
nexus.cleanup.retainDays=30
nexus.scripts.allowCreation=falseConfigure Jetty HTTPS
Create Jetty HTTPS configuration file to define SSL connector settings and security parameters.
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.SslConnectionFactory">
<Arg name="next">http/1.1</Arg>
<Arg name="sslContextFactory">
<New class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
<Set name="KeyStorePath">/opt/sonatype-work/nexus3/etc/ssl/keystore.jks</Set>
<Set name="KeyStorePassword">nexusssl123</Set>
<Set name="KeyManagerPassword">nexusssl123</Set>
<Set name="TrustStorePath">/opt/sonatype-work/nexus3/etc/ssl/keystore.jks</Set>
<Set name="TrustStorePassword">nexusssl123</Set>
<Set name="ExcludeCipherSuites">
<Array type="String">
<Item>SSL_RSA_WITH_DES_CBC_SHA</Item>
<Item>SSL_DHE_RSA_WITH_DES_CBC_SHA</Item>
<Item>SSL_DHE_DSS_WITH_DES_CBC_SHA</Item>
<Item>SSL_RSA_EXPORT_WITH_RC4_40_MD5</Item>
<Item>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</Item>
</Array>
</Set>
<Set name="IncludeProtocols">
<Array type="String">
<Item>TLSv1.2</Item>
<Item>TLSv1.3</Item>
</Array>
</Set>
</New>
</Arg>
</New>
</Item>
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config">
<New class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="secureScheme">https</Set>
<Set name="securePort">8443</Set>
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer"/>
</Arg>
</Call>
</New>
</Arg>
</New>
</Item>
</Array>
</Arg>
<Set name="host">0.0.0.0</Set>
<Set name="port">8443</Set>
<Set name="idleTimeout">30000</Set>
</New>
</Arg>
</Call>
</Configure>Set proper file permissions
Configure correct ownership and permissions for SSL certificates and Nexus configuration files.
# Set ownership for Nexus files
sudo chown -R nexus:nexus /opt/sonatype-work/nexus3/etc/ssl/
sudo chown nexus:nexus /opt/nexus/etc/jetty-https.xml
Set secure permissions for certificates
sudo chmod 600 /opt/sonatype-work/nexus3/etc/ssl/keystore.jks
sudo chmod 600 /opt/sonatype-work/nexus3/etc/ssl/nexus.key
sudo chmod 644 /opt/sonatype-work/nexus3/etc/ssl/nexus.crtConfigure NGINX reverse proxy
Set up NGINX as a reverse proxy with SSL termination and security headers for enhanced protection.
server {
listen 80;
server_name nexus.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name nexus.example.com;
ssl_certificate /etc/letsencrypt/live/nexus.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nexus.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/nexus.example.com/chain.pem;
# SSL Security
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Client settings
client_max_body_size 1G;
client_body_timeout 300s;
location / {
proxy_pass http://127.0.0.1:8081;
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_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffering off;
proxy_request_buffering off;
}
# Docker registry
location /v2/ {
proxy_pass http://127.0.0.1:8081;
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_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffering off;
proxy_request_buffering off;
}
}Enable NGINX configuration
Enable the Nexus NGINX site configuration and restart the service to apply SSL settings.
sudo ln -s /etc/nginx/sites-available/nexus /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable nginxConfigure firewall rules
Open the necessary ports for HTTPS access while maintaining security with specific port rules.
# UFW firewall
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo ufw statusStart Nexus Repository Manager
Start Nexus with the new SSL configuration and verify it starts successfully with HTTPS enabled.
sudo systemctl start nexus
sudo systemctl enable nexus
sudo systemctl status nexus
Check Nexus logs for SSL startup
sudo tail -f /opt/sonatype-work/nexus3/log/nexus.logSecurity hardening configuration
Configure authentication policies
Access Nexus web interface at https://nexus.example.com and configure authentication settings through the administration panel.
# Navigate to: Administration > Security > Realms
Enable: Local Authenticating Realm, Local Authorizing Realm
Optional: LDAP Realm (if using LDAP integration)
Password Policy Settings:
Minimum length: 12 characters
Require uppercase, lowercase, numbers
Maximum age: 90 days
Account lockout: 5 failed attempts
Disable anonymous access
Remove anonymous access capabilities to ensure all repository access requires authentication.
# In Nexus web UI:
Administration > Security > Anonymous Access
Uncheck "Allow anonymous users to access the server"
Save configuration
Configure content trust
Enable content trust and signature validation for Docker images and other artifacts.
# For Docker repositories:
Administration > Repository > Repositories
Edit Docker repositories
Enable "Docker Bearer Token Realm"
Configure content trust validation
Set up audit logging
Configure comprehensive audit logging to track all repository access and administrative actions.
<configuration>
<appender name="AUDIT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${karaf.data}/log/audit.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${karaf.data}/log/audit.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date{ISO8601} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.sonatype.nexus.audit" level="INFO" additivity="false">
<appender-ref ref="AUDIT_FILE"/>
</logger>
<root level="INFO">
<appender-ref ref="AUDIT_FILE"/>
</root>
</configuration>Configure backup encryption
Set up encrypted automated backups of Nexus configuration and data with secure storage.
#!/bin/bash
BACKUP_DIR="/backup/nexus"
DATE=$(date +%Y%m%d_%H%M%S)
GPG_RECIPIENT="admin@example.com"
Create backup directory
mkdir -p $BACKUP_DIR
Stop Nexus for consistent backup
sudo systemctl stop nexus
Create compressed backup
sudo tar czf $BACKUP_DIR/nexus-backup-$DATE.tar.gz \
/opt/sonatype-work/nexus3/db \
/opt/sonatype-work/nexus3/etc \
/opt/sonatype-work/nexus3/blobs
Encrypt backup
gpg --trust-model always --encrypt -r $GPG_RECIPIENT \
$BACKUP_DIR/nexus-backup-$DATE.tar.gz
Remove unencrypted backup
rm $BACKUP_DIR/nexus-backup-$DATE.tar.gz
Start Nexus
sudo systemctl start nexus
Clean old backups (keep 7 days)
find $BACKUP_DIR -name "*.gpg" -mtime +7 -delete
echo "Backup completed: nexus-backup-$DATE.tar.gz.gpg"Set up backup automation
Create a systemd timer for automated daily backups with proper permissions and scheduling.
sudo chmod +x /usr/local/bin/nexus-backup.sh
sudo chown root:root /usr/local/bin/nexus-backup.sh[Unit]
Description=Nexus Repository Backup
After=network.target
[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/nexus-backup.sh
StandardOutput=journal
StandardError=journal[Unit]
Description=Daily Nexus Repository Backup
Requires=nexus-backup.service
[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.targetsudo systemctl daemon-reload
sudo systemctl enable nexus-backup.timer
sudo systemctl start nexus-backup.timer
sudo systemctl status nexus-backup.timerVerify your setup
Test SSL configuration, authentication, and security features to ensure proper operation.
# Test SSL certificate
openssl s_client -connect nexus.example.com:443 -servername nexus.example.com
Test HTTPS redirect
curl -I http://nexus.example.com
Check SSL rating
curl -s "https://api.ssllabs.com/api/v3/analyze?host=nexus.example.com"
Verify Nexus service status
sudo systemctl status nexus nginx
Check listening ports
sudo ss -tlnp | grep -E ':(80|443|8081|8443)'
Test authentication (should require login)
curl -k https://nexus.example.com/service/rest/v1/repositories
Check audit logs
sudo tail -f /opt/sonatype-work/nexus3/log/audit.logAuthentication and authorization
Configure LDAP integration
Integrate Nexus with your organization's LDAP directory for centralized user management and authentication.
For detailed LDAP configuration steps, see our Nexus LDAP authentication tutorial.
Set up role-based access control
Create custom roles and privileges for different user groups with principle of least privilege.
# In Nexus web UI:
Administration > Security > Roles
Developer Role:
- nx-repository-view---browse
- nx-repository-view---read
- nx-repository-view-maven2-*-add
DevOps Role:
- All Developer permissions
- nx-repository-admin---*
- nx-repository-view---edit
Read-Only Role:
- nx-repository-view---browse
- nx-repository-view---read
Configure API tokens
Set up secure API token authentication for automated systems and CI/CD pipelines.
# In Nexus web UI:
Administration > Security > Users
Select user > "Tokens" tab
Generate new token with appropriate permissions
Store token securely in CI/CD system
Monitoring and maintenance
Set up health monitoring
Configure monitoring endpoints and health checks for proactive system monitoring.
#!/bin/bash
NEXUS_URL="https://nexus.example.com"
HEALTH_ENDPOINT="/service/rest/v1/status"
LOG_FILE="/var/log/nexus-health.log"
Check Nexus health
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$NEXUS_URL$HEALTH_ENDPOINT")
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
if [ "$STATUS" = "200" ]; then
echo "$TIMESTAMP - Nexus health check: OK" >> $LOG_FILE
else
echo "$TIMESTAMP - Nexus health check: FAILED (HTTP $STATUS)" >> $LOG_FILE
# Send alert (configure your alerting system)
# systemctl restart nexus
fi
Check disk usage
DISK_USAGE=$(df /opt/sonatype-work | awk 'NR==2{print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 80 ]; then
echo "$TIMESTAMP - Disk usage high: $DISK_USAGE%" >> $LOG_FILE
fi
Check certificate expiry
CERT_DAYS=$(openssl x509 -in /etc/letsencrypt/live/nexus.example.com/cert.pem -noout -dates | grep notAfter | cut -d= -f2 | xargs -I{} date -d "{}" +%s)
CURRENT_DAYS=$(date +%s)
DAYS_LEFT=$(( (CERT_DAYS - CURRENT_DAYS) / 86400 ))
if [ "$DAYS_LEFT" -lt 30 ]; then
echo "$TIMESTAMP - SSL certificate expires in $DAYS_LEFT days" >> $LOG_FILE
fiConfigure log rotation
Set up proper log rotation to prevent disk space issues while maintaining audit trails.
/opt/sonatype-work/nexus3/log/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
copytruncate
maxage 90
}Set up certificate renewal
Configure automatic SSL certificate renewal with Let's Encrypt to maintain continuous HTTPS operation.
# Renew SSL certificates and reload nginx
0 3 * root certbot renew --quiet --post-hook "systemctl reload nginx" >> /var/log/certbot-renewal.log 2>&1Configure performance monitoring
Set up JVM and application performance monitoring for capacity planning and optimization.
For comprehensive monitoring setup, see our guides on Linux system monitoring and Prometheus monitoring.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| SSL handshake failures | Incorrect certificate path or keystore password | Verify keystore location and password in jetty-https.xml |
| 403 Forbidden on repositories | Anonymous access disabled without proper authentication | Configure user authentication or enable anonymous for specific repositories |
| Certificate expired errors | Let's Encrypt certificate not renewed | Run sudo certbot renew and restart nginx |
| High memory usage | Default JVM settings too low for workload | Increase heap size in /opt/nexus/bin/nexus.vmoptions |
| Backup failures | Insufficient disk space or permission issues | Check disk space with df -h and verify backup directory permissions |
| LDAP authentication not working | Incorrect LDAP configuration or network connectivity | Test LDAP connection from Nexus and verify user mapping |
Next steps
- Configure Nexus LDAP authentication for enterprise user management
- Set up Nexus Repository Manager high availability clustering
- Integrate Nexus Repository with Kubernetes and Docker registry
- Configure Nexus Repository monitoring with Prometheus and Grafana
- Set up automated backup and disaster recovery for Nexus Repository