# HTTPS Setup Guide for ROA2WEB on IIS
Complete guide for enabling HTTPS on ROA2WEB deployed on Windows Server with IIS.
---
## ๐ฏ Quick Start
### Option 1: Automated Setup (Recommended)
Run the automated PowerShell script:
```powershell
# On Windows Server (PowerShell as Administrator)
cd C:\path\to\roa2web\deployment\windows\scripts
# Enable HTTPS with self-signed certificate
.\Enable-HTTPS.ps1
# Or specify custom settings
.\Enable-HTTPS.ps1 -IISSiteName "Default Web Site" -CertificateDnsName "10.0.20.36"
```
### Option 2: Manual Setup
Follow the step-by-step instructions in the [Manual Configuration](#manual-configuration) section below.
---
## ๐ Certificate Options
### Self-Signed Certificate (Development/Testing)
**Pros:**
- Quick setup (5 minutes)
- No cost
- Works immediately
**Cons:**
- Browser security warnings
- Not trusted by default
- Not recommended for production
**Use when:**
- Internal development
- Testing HTTPS functionality
- Private internal network
### CA-Issued Certificate (Production)
**Pros:**
- Trusted by all browsers
- No security warnings
- Professional appearance
**Cons:**
- Requires domain name
- May have cost (unless using Let's Encrypt)
- More setup steps
**Use when:**
- Production deployment
- Public-facing application
- Customer/client access
---
## ๐ Automated Setup Details
### Prerequisites
- Windows Server 2016+ (or Windows 10/11 Pro)
- IIS installed and configured
- Administrator privileges
- ROA2WEB already deployed
### Running the Script
**Basic usage (auto-detect settings):**
```powershell
.\Enable-HTTPS.ps1
```
The script will:
1. Auto-detect your server's hostname and IP
2. Create a self-signed certificate
3. Configure HTTPS binding on IIS
4. Enable HTTP to HTTPS redirect
5. Test the configuration
**Custom DNS name:**
```powershell
.\Enable-HTTPS.ps1 -CertificateDnsName "roa2web.company.com"
```
**Use existing certificate:**
```powershell
# List available certificates
Get-ChildItem cert:\LocalMachine\My | Select-Object Thumbprint, Subject, FriendlyName
# Use specific certificate
.\Enable-HTTPS.ps1 -UseExistingCert -CertThumbprint "ABC123..."
```
**For IIS application (not site root):**
```powershell
.\Enable-HTTPS.ps1 -IISSiteName "Default Web Site"
```
**Custom HTTPS port:**
```powershell
.\Enable-HTTPS.ps1 -Port 8443
```
### Script Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `IISSiteName` | String | "Default Web Site" | IIS site name |
| `CertificateDnsName` | String | Auto-detect | DNS name for certificate |
| `UseExistingCert` | Switch | False | Use existing certificate |
| `CertThumbprint` | String | "" | Thumbprint of existing cert |
| `Port` | Int | 443 | HTTPS port |
| `IPAddress` | String | "*" | Bind to specific IP or all (*) |
---
## ๐ง Manual Configuration
### Step 1: Create SSL Certificate
#### Option A: Self-Signed Certificate
```powershell
# Create certificate for IP address (10.0.20.36)
$cert = New-SelfSignedCertificate `
-DnsName "10.0.20.36" `
-CertStoreLocation "cert:\LocalMachine\My" `
-NotAfter (Get-Date).AddYears(5) `
-FriendlyName "ROA2WEB SSL Certificate" `
-KeyUsage DigitalSignature, KeyEncipherment `
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1")
# Display certificate info
$cert | Select-Object Subject, Thumbprint, NotAfter
```
#### Option B: CA-Issued Certificate
**Using IIS Manager:**
1. Open IIS Manager (`inetmgr`)
2. Select your server in the left panel
3. Double-click "Server Certificates"
4. Click "Create Certificate Request..." in right panel
5. Fill in certificate details:
- Common Name: `10.0.20.36` (or your domain)
- Organization: Your company name
- City, State, Country
6. Save the CSR file
7. Submit CSR to Certificate Authority (CA)
8. Once received, import certificate:
- Click "Complete Certificate Request..."
- Browse to certificate file
- Give it a friendly name: "ROA2WEB SSL Certificate"
**Popular Certificate Authorities:**
- **Let's Encrypt** (Free, automated): https://letsencrypt.org/
- **DigiCert** (Commercial): https://www.digicert.com/
- **Sectigo** (Commercial): https://sectigo.com/
- **GlobalSign** (Commercial): https://www.globalsign.com/
### Step 2: Configure HTTPS Binding
```powershell
Import-Module WebAdministration
# Add HTTPS binding to site
New-WebBinding -Name "Default Web Site" -Protocol "https" -Port 443 -IPAddress "*"
# Attach certificate to binding
$cert = Get-ChildItem -Path "cert:\LocalMachine\My" |
Where-Object {$_.FriendlyName -eq "ROA2WEB SSL Certificate"}
Push-Location
Set-Location IIS:\SslBindings
$cert | New-Item "0.0.0.0!443"
Pop-Location
```
### Step 3: Enable HTTP to HTTPS Redirect
**Option A: Automatic (via script)**
The `Enable-HTTPS.ps1` script will offer to add the redirect rule automatically.
**Option B: Manual Edit**
Edit `C:\inetpub\wwwroot\roa2web\frontend\web.config`:
```xml
```
**Option C: IIS Manager GUI**
1. Open IIS Manager
2. Navigate to your site
3. Double-click "URL Rewrite"
4. Click "Add Rule(s)..." โ "Blank rule"
5. Configure:
- Name: `Force HTTPS`
- Match URL: `(.*)`
- Conditions: Add condition
- Input: `{HTTPS}`
- Pattern: `off`
- Action:
- Type: `Redirect`
- URL: `https://{HTTP_HOST}/{R:1}`
- Redirect type: `Permanent (301)`
### Step 4: Test Configuration
```powershell
# Restart IIS site
Restart-Website "Default Web Site"
# Test HTTPS locally (self-signed cert)
Invoke-WebRequest https://localhost -SkipCertificateCheck
# Test from browser
Start-Process "https://10.0.20.36/roa2web"
```
---
## ๐งช Testing HTTPS Configuration
### Browser Testing
1. **Access via HTTPS:**
```
https://10.0.20.36/roa2web
```
2. **Check for security warnings:**
- **Self-signed cert**: You'll see a warning - this is normal
- **CA-issued cert**: No warning - connection is secure
3. **Verify redirect:**
- Try accessing: `http://10.0.20.36/roa2web`
- Should automatically redirect to: `https://10.0.20.36/roa2web`
4. **Check console for mixed content:**
- Open browser DevTools (F12)
- Look for mixed content warnings
- All resources should load over HTTPS
### PowerShell Testing
```powershell
# Test HTTPS binding
Get-WebBinding -Name "Default Web Site" -Protocol "https"
# Test certificate
$cert = Get-ChildItem cert:\LocalMachine\My |
Where-Object {$_.FriendlyName -eq "ROA2WEB SSL Certificate"}
$cert | Select-Object Subject, Thumbprint, NotAfter, DnsNameList
# Test HTTPS response
Invoke-WebRequest https://localhost/roa2web -SkipCertificateCheck
# Test from external IP
Invoke-WebRequest https://10.0.20.36/roa2web -SkipCertificateCheck
# View IIS SSL bindings
netsh http show sslcert
```
### Network Testing
```bash
# Test from Linux/Mac client
curl -k https://10.0.20.36/roa2web
# Check certificate details
openssl s_client -connect 10.0.20.36:443 -servername 10.0.20.36
# Test redirect
curl -I http://10.0.20.36/roa2web
# Should return: HTTP/1.1 301 Moved Permanently
# Location: https://10.0.20.36/roa2web
```
---
## ๐ Troubleshooting
### HTTPS Not Working
**Symptom:** Can't access site via HTTPS
**Check:**
```powershell
# Verify HTTPS binding exists
Get-WebBinding -Name "Default Web Site"
# Check if port 443 is listening
netstat -ano | findstr :443
# View SSL certificate bindings
netsh http show sslcert
```
**Fix:**
```powershell
# Remove and recreate binding
Remove-WebBinding -Name "Default Web Site" -Protocol "https" -Port 443
New-WebBinding -Name "Default Web Site" -Protocol "https" -Port 443
# Reattach certificate
$cert = Get-ChildItem cert:\LocalMachine\My |
Where-Object {$_.FriendlyName -eq "ROA2WEB SSL Certificate"}
Push-Location IIS:\SslBindings
$cert | New-Item "0.0.0.0!443" -Force
Pop-Location
```
### Certificate Warning in Browser
**Symptom:** Browser shows "Your connection is not private" or similar warning
**Cause:**
- Self-signed certificate (not trusted by default)
- Expired certificate
- Hostname mismatch
**Solutions:**
1. **For Development (self-signed):**
- Click "Advanced" โ "Proceed anyway"
- This is expected behavior for self-signed certificates
2. **For Production:**
- Replace with CA-issued certificate
- Ensure certificate CN matches the URL you're accessing
3. **For Internal Network:**
- Add certificate to Trusted Root CA:
```powershell
$cert = Get-ChildItem cert:\LocalMachine\My\
$store = Get-Item cert:\LocalMachine\Root
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()
```
### HTTP Not Redirecting to HTTPS
**Symptom:** HTTP URLs still work, no automatic redirect
**Check:**
```powershell
# Verify web.config has redirect rule
Get-Content C:\inetpub\wwwroot\roa2web\frontend\web.config |
Select-String "Force HTTPS"
```
**Fix:**
- Ensure redirect rule is present in web.config
- Verify rule is BEFORE other rewrite rules
- Check rule is not disabled
- Restart IIS site:
```powershell
Restart-Website "Default Web Site"
```
### Mixed Content Warnings
**Symptom:** Console shows "Mixed Content" warnings
**Cause:** Some resources loading over HTTP instead of HTTPS
**Fix:**
1. Check frontend code for hardcoded `http://` URLs
2. Update to use relative URLs or `https://`
3. Update API base URL in frontend config:
```javascript
// src/config.js or similar
const API_BASE_URL = window.location.protocol === 'https:'
? 'https://10.0.20.36/api'
: 'http://10.0.20.36/api';
```
### API Calls Failing After HTTPS
**Symptom:** Frontend loads but API calls fail with CORS or SSL errors
**Check:**
```powershell
# Verify backend is accessible
Invoke-WebRequest http://localhost:8000/health
# Check IIS URL Rewrite is forwarding correctly
Get-WebConfiguration -Filter "system.webServer/rewrite/rules"
```
**Fix:**
- Update CORS settings in FastAPI backend to allow HTTPS origin
- Verify web.config proxy rules are correct
- Check backend logs for errors
---
## ๐ Security Best Practices
### 1. Use Strong Certificates
```powershell
# For production, use CA-issued certificates
# Minimum key size: 2048 bits (4096 recommended)
# Use SHA-256 or higher
```
### 2. Enable HSTS (Strict Transport Security)
Already configured in `web.config` (lines 115-124):
```xml
```
This tells browsers to always use HTTPS for your site.
### 3. Disable Weak SSL/TLS Protocols
```powershell
# Disable SSL 2.0, SSL 3.0, TLS 1.0, TLS 1.1
# Enable only TLS 1.2 and TLS 1.3
# Run as Administrator
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Force
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Name 'Enabled' -Value 1 -PropertyType 'DWord'
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server' -Name 'DisabledByDefault' -Value 0 -PropertyType 'DWord'
# Restart required
Restart-Computer
```
### 4. Secure Cookie Settings
Update FastAPI backend cookie settings:
```python
# backend/app/main.py
response.set_cookie(
key="access_token",
value=token,
httponly=True,
secure=True, # Only send over HTTPS
samesite="lax"
)
```
### 5. Regular Certificate Renewal
- CA certificates typically expire in 1-2 years
- Let's Encrypt certificates expire in 90 days
- Set up reminders or automated renewal
```powershell
# Check certificate expiry
$cert = Get-ChildItem cert:\LocalMachine\My |
Where-Object {$_.FriendlyName -eq "ROA2WEB SSL Certificate"}
$cert.NotAfter
# Days until expiry
($cert.NotAfter - (Get-Date)).Days
```
---
## ๐ Additional Resources
### Documentation
- [IIS SSL Configuration](https://docs.microsoft.com/en-us/iis/manage/configuring-security/how-to-set-up-ssl-on-iis)
- [Let's Encrypt](https://letsencrypt.org/)
- [SSL/TLS Best Practices](https://wiki.mozilla.org/Security/Server_Side_TLS)
### Testing Tools
- [SSL Labs Server Test](https://www.ssllabs.com/ssltest/) - Comprehensive SSL/TLS analysis
- [SSL Checker](https://www.sslshopper.com/ssl-checker.html) - Quick certificate validation
- [Why No Padlock?](https://www.whynopadlock.com/) - Find mixed content issues
### Certificate Providers
- **Free:**
- [Let's Encrypt](https://letsencrypt.org/) (Automated, 90-day validity)
- [ZeroSSL](https://zerossl.com/) (Free tier available)
- **Commercial:**
- [DigiCert](https://www.digicert.com/)
- [Sectigo](https://sectigo.com/)
- [GlobalSign](https://www.globalsign.com/)
---
## โ
Quick Reference
### Essential Commands
```powershell
# View all certificates
Get-ChildItem cert:\LocalMachine\My
# View IIS bindings
Get-WebBinding -Name "Default Web Site"
# View SSL bindings
netsh http show sslcert
# Test HTTPS
Invoke-WebRequest https://localhost -SkipCertificateCheck
# Restart IIS site
Restart-Website "Default Web Site"
# Enable HTTPS (automated script)
.\Enable-HTTPS.ps1
```
### Configuration Files
- **IIS bindings**: IIS Manager โ Site โ Bindings
- **web.config**: `C:\inetpub\wwwroot\roa2web\frontend\web.config`
- **Certificates**: Certificate Manager (`certmgr.msc`)
- **Backend config**: `C:\inetpub\wwwroot\roa2web\backend\.env`
### Access Points
- **HTTP**: `http://10.0.20.36/roa2web` (redirects to HTTPS)
- **HTTPS**: `https://10.0.20.36/roa2web`
- **API**: `https://10.0.20.36/api/*` (proxied to backend)
- **Health**: `https://10.0.20.36/health`
---
*Last Updated: 2025-01-18*
*ROA2WEB HTTPS Setup Guide v1.0*