|
|
@ -26,3 +26,134 @@ RewriteRule /wetty/socket.io/(.*) ws://localhost:3000/wetty/socket.io/$1 [P,L] |
|
|
|
ProxyPassReverse /wetty/ |
|
|
|
</LocationMatch> |
|
|
|
``` |
|
|
|
|
|
|
|
## SAML2 integration to auth users |
|
|
|
|
|
|
|
This conf is using apache2 (as for nginx, SAML2 integration is not |
|
|
|
available on the community version, only pro). |
|
|
|
|
|
|
|
Main idea is to propagate the SAML2 validated user identity into the |
|
|
|
`remote-user` HTTP header. You need to have the user id returned |
|
|
|
within the SAML2 NameID matching the username defined on the platform |
|
|
|
wetty is running. |
|
|
|
|
|
|
|
E.g: You can ask the Idp to return a sAMAccountName within the |
|
|
|
SAML2Response NameID, and provision beforehand those allowed users on |
|
|
|
the OS wetty is running on. |
|
|
|
|
|
|
|
### SAML2 Metadata generation |
|
|
|
|
|
|
|
SAML2 metadata needs to be generated for this new service on the |
|
|
|
server and exchanged with the Idp. We will use the script provided at |
|
|
|
https://raw.githubusercontent.com/bitsensor/saml-proxy/master/mellon_create_metadata.sh |
|
|
|
|
|
|
|
``` |
|
|
|
$ mellon_create_metadata.sh urn:https://foo.bar.tlz https://foo.bar.tld/mellon |
|
|
|
``` |
|
|
|
|
|
|
|
Then we move the generated files over |
|
|
|
`/etc/apache2/saml2/foo.{xml,key,cert}`. |
|
|
|
|
|
|
|
You need to put here additionaly the metadata from your SAML2 |
|
|
|
provider, named here `idp.xml` and exchange you foo.xml with it. |
|
|
|
|
|
|
|
|
|
|
|
### Apache2 conf |
|
|
|
|
|
|
|
``` apache |
|
|
|
<VirtualHost *:443> |
|
|
|
ServerName foo.bar.tld |
|
|
|
ServerAdmin admin@bar.tld |
|
|
|
|
|
|
|
SSLEngine on |
|
|
|
SSLCertificateFile /etc/apache2/ssl/foo.pem |
|
|
|
SSLCertificateKeyFile /etc/apache2/ssl/foo.key |
|
|
|
|
|
|
|
RedirectMatch ^/$ /wetty/ |
|
|
|
ProxyPass "/wetty" "http://127.0.0.1:3000/wetty" |
|
|
|
|
|
|
|
<Location / > |
|
|
|
AuthType Mellon |
|
|
|
MellonEnable info |
|
|
|
|
|
|
|
# this propagates to apache2 (and thus to access log) the proper user id, and not |
|
|
|
# the transiant nameid that is taken by default |
|
|
|
# it has no impact on the backend as we propagate identify via remote-user header there |
|
|
|
MellonUser "NameID" |
|
|
|
|
|
|
|
MellonEndpointPath /mellon/ |
|
|
|
MellonSPMetadataFile /etc/apache2/saml2/foo.xml |
|
|
|
MellonSPPrivateKeyFile /etc/apache2/saml2/foo.key |
|
|
|
MellonSPCertFile /etc/apache2/saml2/foo.cert |
|
|
|
MellonIdPMetadataFile /etc/apache2/saml2/idp.xml |
|
|
|
|
|
|
|
# the identity propagated to wetty (as HTTP header 'remote-user: xxxxx') |
|
|
|
# is retrieved from SAMLResponse NameID attribute |
|
|
|
RequestHeader set remote-user %{MELLON_NAMEID}e |
|
|
|
</Location> |
|
|
|
|
|
|
|
<Location /wetty> |
|
|
|
AuthType Mellon |
|
|
|
MellonEnable auth |
|
|
|
Require valid-user |
|
|
|
</Location> |
|
|
|
|
|
|
|
# security hazard for switching between users, disabled if remote-user set as recent github commit |
|
|
|
# but not yet published via yarn, so we put here a double security belt |
|
|
|
<Location /wetty/ssh/> |
|
|
|
Deny from all |
|
|
|
</Location> |
|
|
|
</VirtualHost> |
|
|
|
``` |
|
|
|
|
|
|
|
### Auto login |
|
|
|
|
|
|
|
If you want to have a seamless login by trusting your IdP for |
|
|
|
authentication, you can create password-less users on the wetty |
|
|
|
platform and have them trust an SSH key used by the NodeJS, owned by |
|
|
|
the dedicated wetty OS user. |
|
|
|
|
|
|
|
Wetty instanciation with proper parameters, especially the SSH private |
|
|
|
key is done via the following systemd service |
|
|
|
`/etc/systemd/system/wetty.service`: |
|
|
|
|
|
|
|
``` |
|
|
|
[Unit] |
|
|
|
Description=Wetty Web Terminal |
|
|
|
After=network.target |
|
|
|
|
|
|
|
[Service] |
|
|
|
User=wetty |
|
|
|
Type=simple |
|
|
|
WorkingDirectory=/home/wetty/.config/yarn/global/node_modules/wetty/ |
|
|
|
ExecStart=/usr/bin/node . -p 3000 --host 127.0.0.1 --ssh-key /home/wetty/.ssh/wetty --ssh-auth publickey --force-ssh --title "Foo bar terminal services" |
|
|
|
TimeoutStopSec=20 |
|
|
|
KillMode=mixed |
|
|
|
Restart=always |
|
|
|
RestartSec=2 |
|
|
|
|
|
|
|
[Install] |
|
|
|
WantedBy=multi-user.target |
|
|
|
``` |
|
|
|
|
|
|
|
For your new users to be automically trusting this SSH key when |
|
|
|
provisionning, you may add the pubkey to |
|
|
|
`/etc/skel/.ssh/authorized_keys`. |
|
|
|
|
|
|
|
|
|
|
|
### Security precautions |
|
|
|
|
|
|
|
You probably don't want local users to impersonate each other, for that you need to make sure that: |
|
|
|
|
|
|
|
1. NodeJS is listenning only to localhost: provided by `wetty.service` |
|
|
|
2. **Only** the apache2 process can join the wetty port. Else local users |
|
|
|
will be able to connect and forge a `remote-user` header: provided |
|
|
|
by `iptables -A OUTPUT -o lo -p tcp --dport 3000 -m owner \! |
|
|
|
--uid-owner www-data -j DROP` |
|
|
|
3. Validate your wetty version does not allow access to `/wetty/ssh/` |
|
|
|
else again you will be able to impersonnate anyone: provided by |
|
|
|
either: |
|
|
|
1. wetty version 2.0.3 and beyond implements this by disabling this feature in case of `remote-user` |
|
|
|
presence |
|
|
|
2. apache2 conf as provided in previous section (containing the |
|
|
|
`<Location /wetty/ssh/>`) |
|
|
|