diff --git a/auth/auth.js b/auth/auth.js index d7437b7..46c1016 100755 --- a/auth/auth.js +++ b/auth/auth.js @@ -15,9 +15,9 @@ app.post("/api/login", (req,res)=>{ // Set Session Cookie res.cookie("SESSIONID", "dummy-session-"+user, { httpOnly: true, - secure: false, // in production: set to true when serving over HTTPS - // domain: ".server.schooltech.ch", // removed for local dev; set in production - sameSite: "Lax", // local dev; use "None" + secure:true for iframe production + secure: true, // production: require HTTPS + domain: ".server.schooltech.ch", // allow cookie for subdomains + sameSite: "None", // required for third-party iframes over HTTPS path: "/" }); res.status(200).send({ ok:true }); diff --git a/certs/private/server.key b/certs/private/server.key new file mode 100644 index 0000000..e3242dd --- /dev/null +++ b/certs/private/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCudB7U5+pbHu0P +fBs2Ot+d2TFy+j6T1xD2PJN8ns+FKP2zyEBOnbiZiVzCpscS/4U5CemmpNfo5NKR +LuKA7YOKJfcdkpvLGfvGeLPdyQPmlcO3wUpzNkzMKH28Qxpw7dRmHTGhmCCLftdT +ObOQnotercnV2dGaH2DLsgR9uvTAW/wm1sCxXjOuPAx9wUHwYsG/i0Q/IxR+Cwjb +v59UlR6vZgUeqBSf+KbbzOK+nO1lmmg1t2Kv/BRfX42KG6YchYsnFzWXi1XCmCGo +6sYloBnj/Q/j5m784CF6iZUB87QDqyobW3EBD/EpGX9aiSxAwTJ9cLkb1ee7Bt0R +/ErAClpbAgMBAAECggEAQWqbsRxx3c9f94GDNrem6KrsBwBdfNSVsLAQYhevG3C+ +ia7apmAwO6qtlPQzDCWy0CuuaOXBbLx5VSWum8f0nlYULwutzeAlcEwMrmrVQp8A +MCSUBVXkQF4in/jNrnEQR2ZFGSJRed2LYtLtSZqaClvCpqUyGsgPZPKRCpCTfJmi +nOyIvCRSD4wS2R5+EX6cW+z/VHE0TvoEVqzWjR1Zq9SppOmZ9BrD8gamqnXqqAKU +M6THywfFv5F/N78j35WHMfc17mM/b9RIvP5ALxo3/J+W4aEEhe67j1G4C2RyW5jc +J/ya7wqLSKaVOOo+ICQpfAnIlavIYTdnw7dQzshcaQKBgQDkrwUuyZbcwdTBkSpK +6Z6bEvzv/Kp8pWznvFqT0TT6eOvYQO4K2MDR6XXqYNTYPKV11CWjd1ZuOL+wH6/n +ayyfsDQCC/celjHUe2LhIyVoFzFwAqcVNVf5o3rYfFKsQ55Z3Qs1406kChmlHg6M +rn/7atdqTG6a7Ssu8rtBpxxrFQKBgQDDSsi1Y63QyLE6o+f3Xs3sf9o/CRPndkw8 +wyuc+lmkt1VLNyz7VS9kubofjeRdJJGbcryj1jMdjErvxKEQQu6y8lC89hTY+zaI +gBNzUwUgVl4wD4AaDFWF/+ZrIdFY63IEn0SLNN2Z4fI9GYOvjrsUAbMVau1GEHTy +b6RTZsZLrwKBgGgK/QepbfroMR0UJ7LHkYKqY+vn/8UQGnlgZ7Fi+ICQrXTJLcQ/ +k5KtbhmBjrUG+pyeNbWmoOsq5IOEFyrpxvasWy0nNnpzCR7MOFOIAwfVrYdxnYT3 +rRwF9ekyvwZjCVOHTwdocKoPclV+VE5LQi0oEfPp7FSOXRxSEUIwfqx1AoGBAIcS +Yl+S4dVV+b6lPvtJBwRcKYcPsESW/YPJOZEJVpcmdkffka0D7hOsoZ7RdPE3Kb5q +TS7EJ/Z34hyT0xJ8OLxr/Iu1aBXrKnyemNVaxmDnW53CGsfpX/2eULAoY7MspV+t +CKt/lQWp0PGRhBMYlSvxQPu/SPz8xOYpcW591wjhAoGAT7vLLa5Tx20NxdvH7mB6 +mb0qOBXa139w4YplZ0cf77wxLCPh4U9hyEmk+R1zXJZqDcVGR7VjOxKCu2IydevE +BCbUMYrBZ+fJzUbl+ZyqprX2BuyZQKQ86JZBvwg4xt/UXFA8MOg2UfCdx2JyG3MG +3qkCXqVrjEDlKDkCPIpLGq0= +-----END PRIVATE KEY----- diff --git a/certs/server.crt b/certs/server.crt new file mode 100644 index 0000000..73590e2 --- /dev/null +++ b/certs/server.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIUbkOGhIlTBwWCe/ifnAhXPxnGEXYwDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUc2VydmVyLnNjaG9vbHRlY2guY2gwHhcNMjYwMjAzMDYw +NzUzWhcNMjcwMjAzMDYwNzUzWjAfMR0wGwYDVQQDDBRzZXJ2ZXIuc2Nob29sdGVj +aC5jaDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK50HtTn6lse7Q98 +GzY6353ZMXL6PpPXEPY8k3yez4Uo/bPIQE6duJmJXMKmxxL/hTkJ6aak1+jk0pEu +4oDtg4ol9x2Sm8sZ+8Z4s93JA+aVw7fBSnM2TMwofbxDGnDt1GYdMaGYIIt+11M5 +s5Cei16tydXZ0ZofYMuyBH269MBb/CbWwLFeM648DH3BQfBiwb+LRD8jFH4LCNu/ +n1SVHq9mBR6oFJ/4ptvM4r6c7WWaaDW3Yq/8FF9fjYobphyFiycXNZeLVcKYIajq +xiWgGeP9D+PmbvzgIXqJlQHztAOrKhtbcQEP8SkZf1qJLEDBMn1wuRvV57sG3RH8 +SsAKWlsCAwEAAaOBjTCBijAdBgNVHQ4EFgQUwjY/xuS1hqbtwWiZkMDyLKfn9XUw +HwYDVR0jBBgwFoAUwjY/xuS1hqbtwWiZkMDyLKfn9XUwDwYDVR0TAQH/BAUwAwEB +/zA3BgNVHREEMDAughRzZXJ2ZXIuc2Nob29sdGVjaC5jaIIWKi5zZXJ2ZXIuc2No +b29sdGVjaC5jaDANBgkqhkiG9w0BAQsFAAOCAQEAWH9akh4Bh7rZMJjV4kJriH2R +ZdYdun90L+Vvz3K9AGIKeEWpPWsPGQEwb7YkgMYDtyBx1ErDSWpuoXkccxZWjHfY +iAUSI6X4cL8N7ieMYcQchT6H1Jzomm2nCgwYKW8BDXgl9UyeIhsw14epugmDyF19 +2fwg02fnJkrSciOWWk5JXN2Bb93vVbe+BCBIEVMKDAhaR1pbowFTx5G4Fo+ULfQQ +Otn3Vo4ZD29VbcAmj6D7RYxvzPb0YuiBr+S6GNFlFct+1Xc6AgLuOV7RS66ZuWLL +SYoIj2sDc1U+61Kc4Of4LteLSXGahJA1q/bbQAKfB83jrUZbT9XHB8FDdhhNIg== +-----END CERTIFICATE----- diff --git a/certs/server.key b/certs/server.key new file mode 100644 index 0000000..e3242dd --- /dev/null +++ b/certs/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCudB7U5+pbHu0P +fBs2Ot+d2TFy+j6T1xD2PJN8ns+FKP2zyEBOnbiZiVzCpscS/4U5CemmpNfo5NKR +LuKA7YOKJfcdkpvLGfvGeLPdyQPmlcO3wUpzNkzMKH28Qxpw7dRmHTGhmCCLftdT +ObOQnotercnV2dGaH2DLsgR9uvTAW/wm1sCxXjOuPAx9wUHwYsG/i0Q/IxR+Cwjb +v59UlR6vZgUeqBSf+KbbzOK+nO1lmmg1t2Kv/BRfX42KG6YchYsnFzWXi1XCmCGo +6sYloBnj/Q/j5m784CF6iZUB87QDqyobW3EBD/EpGX9aiSxAwTJ9cLkb1ee7Bt0R +/ErAClpbAgMBAAECggEAQWqbsRxx3c9f94GDNrem6KrsBwBdfNSVsLAQYhevG3C+ +ia7apmAwO6qtlPQzDCWy0CuuaOXBbLx5VSWum8f0nlYULwutzeAlcEwMrmrVQp8A +MCSUBVXkQF4in/jNrnEQR2ZFGSJRed2LYtLtSZqaClvCpqUyGsgPZPKRCpCTfJmi +nOyIvCRSD4wS2R5+EX6cW+z/VHE0TvoEVqzWjR1Zq9SppOmZ9BrD8gamqnXqqAKU +M6THywfFv5F/N78j35WHMfc17mM/b9RIvP5ALxo3/J+W4aEEhe67j1G4C2RyW5jc +J/ya7wqLSKaVOOo+ICQpfAnIlavIYTdnw7dQzshcaQKBgQDkrwUuyZbcwdTBkSpK +6Z6bEvzv/Kp8pWznvFqT0TT6eOvYQO4K2MDR6XXqYNTYPKV11CWjd1ZuOL+wH6/n +ayyfsDQCC/celjHUe2LhIyVoFzFwAqcVNVf5o3rYfFKsQ55Z3Qs1406kChmlHg6M +rn/7atdqTG6a7Ssu8rtBpxxrFQKBgQDDSsi1Y63QyLE6o+f3Xs3sf9o/CRPndkw8 +wyuc+lmkt1VLNyz7VS9kubofjeRdJJGbcryj1jMdjErvxKEQQu6y8lC89hTY+zaI +gBNzUwUgVl4wD4AaDFWF/+ZrIdFY63IEn0SLNN2Z4fI9GYOvjrsUAbMVau1GEHTy +b6RTZsZLrwKBgGgK/QepbfroMR0UJ7LHkYKqY+vn/8UQGnlgZ7Fi+ICQrXTJLcQ/ +k5KtbhmBjrUG+pyeNbWmoOsq5IOEFyrpxvasWy0nNnpzCR7MOFOIAwfVrYdxnYT3 +rRwF9ekyvwZjCVOHTwdocKoPclV+VE5LQi0oEfPp7FSOXRxSEUIwfqx1AoGBAIcS +Yl+S4dVV+b6lPvtJBwRcKYcPsESW/YPJOZEJVpcmdkffka0D7hOsoZ7RdPE3Kb5q +TS7EJ/Z34hyT0xJ8OLxr/Iu1aBXrKnyemNVaxmDnW53CGsfpX/2eULAoY7MspV+t +CKt/lQWp0PGRhBMYlSvxQPu/SPz8xOYpcW591wjhAoGAT7vLLa5Tx20NxdvH7mB6 +mb0qOBXa139w4YplZ0cf77wxLCPh4U9hyEmk+R1zXJZqDcVGR7VjOxKCu2IydevE +BCbUMYrBZ+fJzUbl+ZyqprX2BuyZQKQ86JZBvwg4xt/UXFA8MOg2UfCdx2JyG3MG +3qkCXqVrjEDlKDkCPIpLGq0= +-----END PRIVATE KEY----- diff --git a/docker-compose.yaml b/docker-compose.yaml index 07d880a..9f2e4dd 100755 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,8 +7,10 @@ services: volumes: - /home/chk/Documents/AppServerPortalUI/nginx.conf:/etc/nginx/conf.d/default.conf:ro - /home/chk/Documents/AppServerPortalUI/public:/usr/share/nginx/html:ro + - /home/chk/Documents/AppServerPortalUI/certs:/etc/ssl:ro ports: - "5080:80" + - "443:443" networks: - default restart: unless-stopped diff --git a/nginx.conf b/nginx.conf index 429aace..92b723a 100755 --- a/nginx.conf +++ b/nginx.conf @@ -1,8 +1,21 @@ error_log /var/log/nginx/error.log info; +# Default HTTP -> HTTPS redirect (keine Änderung) server { listen 80 default_server; server_name _; + return 301 https://$host$request_uri; +} + +# UI (portal) - nur für server.schooltech.ch +server { + listen 443 ssl http2; + server_name server.schooltech.ch; + + ssl_certificate /etc/ssl/certs/server.crt; + ssl_certificate_key /etc/ssl/private/server.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; root /usr/share/nginx/html; index index.html; @@ -11,56 +24,85 @@ server { try_files $uri $uri/ /index.html; } - # API calls to Auth service inside Docker network + # API forwarding to auth (same as before) location /api/ { proxy_pass http://appserverauth:3000/api/; 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; } + + # Internal auth endpoint for auth_request (used by other server blocks) + location = /nginxauth { + internal; + proxy_pass http://appserverauth:3000/internal/auth; + proxy_set_header Cookie $http_cookie; + } + + # Security + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; } + server { - listen 80; + listen 443 ssl http2; server_name abc.server.schooltech.ch; + ssl_certificate /etc/ssl/certs/server.crt; + ssl_certificate_key /etc/ssl/private/server.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + + # Auth-Request auth_request /nginxauth; location / { proxy_pass https://thinkcentre.local:10010/; - # WebSocket and HTTPS upstream settings + # WebSocket Support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + + # SSL zum Upstream proxy_ssl_server_name on; - proxy_ssl_name abc.server.schooltech.ch; + proxy_ssl_name thinkcentre.local; # proxy_ssl_name abc.server.schooltech.ch; proxy_ssl_verify off; - proxy_set_header Host abc.server.schooltech.ch; + # Standard Proxy Header + proxy_set_header Host thinkcentre.local; # proxy_set_header Host abc.server.schooltech.ch; 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_set_header X-Forwarded-Proto https; proxy_set_header Origin $http_origin; # iFrame erlauben proxy_hide_header X-Frame-Options; - add_header X-Frame-Options "ALLOWALL"; + add_header X-Frame-Options "ALLOWALL" always; + proxy_hide_header Content-Security-Policy; - add_header Content-Security-Policy "frame-ancestors *"; + add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always; # add_header Content-Security-Policy "frame-ancestors *" always; } location = /nginxauth { internal; proxy_pass http://appserverauth:3000/internal/auth; proxy_set_header Cookie $http_cookie; + proxy_set_header X-Original-URI $request_uri; } } + server { - listen 80; + listen 443 ssl http2; server_name xyz.server.schooltech.ch; + ssl_certificate /etc/ssl/certs/server.crt; + ssl_certificate_key /etc/ssl/private/server.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + auth_request /nginxauth; location / { @@ -71,22 +113,25 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + # Proxy Header proxy_set_header Host xyz.server.schooltech.ch; proxy_set_header Origin $http_origin; 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_set_header X-Forwarded-Proto https; - # iFrame erlauben + # iFrame erlauben proxy_hide_header X-Frame-Options; - add_header X-Frame-Options "ALLOWALL"; + add_header X-Frame-Options "ALLOWALL" always; + proxy_hide_header Content-Security-Policy; - add_header Content-Security-Policy "frame-ancestors *"; + add_header Content-Security-Policy "frame-ancestors *" always; } location = /nginxauth { internal; proxy_pass http://appserverauth:3000/internal/auth; proxy_set_header Cookie $http_cookie; + proxy_set_header X-Original-URI $request_uri; } } \ No newline at end of file diff --git a/public/app.js b/public/app.js index 3952995..e791ee7 100755 --- a/public/app.js +++ b/public/app.js @@ -2,8 +2,8 @@ // Service-Liste const services = [ - { id: "abc", name: "Control GamePad", url: "https://abc.server.schooltech.ch" }, - { id: "xyz", name: "Guacamole", url: "https://xyz.server.schooltech.ch" } + { id: "abc", name: "Control GamePad", url: "https://abc.server.schooltech.ch/" }, + { id: "xyz", name: "Guacamole", url: "https://xyz.server.schooltech.ch/" } ]; // DOM-Elemente @@ -82,3 +82,14 @@ function logout() { nav.innerHTML = ""; loginModal.style.display = "block"; } + +// Setzen des Cookies für die Sitzung +function setSessionCookie(res, user) { + res.cookie("SESSIONID", "session-"+user, { + httpOnly: true, + secure: true, // zwingend bei SameSite=None + domain: ".server.schooltech.ch", + sameSite: "None", + path: "/" + }); +}