Shared web hosting with SSH access

We have just added optional SSH/SCP access (SFTP/SSHFS access was the only previous option) to our shared hosting service and are rather pleased with the implementation we have come up with.

With SFTP/SSHFS access users are jailed in their home directory and don’t have any way to see any other files on the servers — this is what we have had for years.

With SSH/SCP access users are jailed into a chroot which is a, read-only mounted, copy of a minimal Debian install with their home directory mounted read-write, this means you can’t see any other users files and while MySQL works as the socket is mounted (for TCP connections to localhost, otherwise only 127.0.0.1 works) and all the tools we could think of are installed, wp, drush, composer, vim etc. this isn’t the environment that Apache and MySQL are actually running in so there are no logs or server configurations available.

One thing I was wondering is what other command line tools do people use when they have SSH access to shared hosting servers and are setting sites up? Is there anything we could add?

Something we haven’t sorted out is access to the crontab and of course some environmental variables might have different values when accessed via the web.

3 Likes

I’ve spent a fair amount of time over the last year writing around 20k lines of Ansible to provision our shared hosting servers and today we have launched version 0.9:

The main change is a switch away from Apache and mod_php to Apache with PHP FPM in a chroot. All users now have SSH and SFTP access and we have been doing everything we can to make this service as developer friendly as possible.

By the end of the year we hope to have version 1.0 ready and this will come with client accessible backups and in additional to SSH and PHP being chrooted we will chroot MariaDB to ensure total even more total user isolation so that in the event of a site being compromised no other users will be endangered.

4 Likes

Nice one @chris ! I dont understand any of this but it sounds groovy so congratulations!

Hope to hear more about it at the gathering…

1 Like

I’d be happy to do a short session on this for anyone interested :slight_smile:

This is neat! Thanks Chris!

Back to one of original questions:

One thing I was wondering is what other command line tools do people use when they have SSH access to shared hosting servers and are setting sites up? Is there anything we could add?

I’m hoping to eventually try this if my fellow cooperators are onboard for the experiment: https://keybase.io/blog/keybase-ssh-ca

Of course, this would make more sense if we decided to use keybase chat and keybaseFS, or manage member identities canonically via keybase and its team feature. There seem to be pros and cons to that :slight_smile:

So far, we’re only using keybase to supplement our digital signing process on legal documents. E.g., https://github.com/hyphacoop/handbook/issues/21

I’d be on for trying this at some point, but it appears to me that it isn’t something suitable for shared servers that you don’t have root on?

1 Like

Hi.

From what I remember, keybase is to be run on your desktop, not on
servers. I looked at that blog post and certainly recognize the problem
it describes. I don’t really like that solution, as it depends on a
centralized outside service. I had an account on keybase but abandoned
it after reading about a number of issues, privacy related and it’s
impossible to self-host. Found a list here:

As for good solutions for credential sharing, with good team support,
I’m not sure. I guess Vault (from hashicorp but server side is foss,
though maybe just the core) and Gluu (https://www.gluu.org/) could be
evaluated.

This looks very interesting. I will take a deeper dive soon.

As an aside, there is a set of very well maintained Ansible playbooks
that I use, called Debops [https://debops.org/]. It basically intends to
manage Debian based infrastructures using Ansible and does a very good
job at it. There are playbooks for PHP hosting and this work you did
would fit wonderfully there. There is overlap, as there is a lot already
taken care of in the other DebOps playbooks.

Anyway, just wanted to make sure you all know of that effort.
Congratulations and thanks :slight_smile:

2 Likes

Thanks for that @zeh, I did look at Debops when I started learning Ansible and was put off by it’s extensive nature (it appeared far to complicated for what I wanted to start using Ansible for, I wanted to get stuck in and do things from scratch straight away), I would be interested in using it someday and I’m sure there is a lot I could learn from it and I expect there are parts I could copy or simply use as replacements.

I’ve been using Ansible and learning as I go on for almost 3 years and after doing things using Bash, Git and Subversion and before that CVS it’s been really good to switch to Ansible and GitLab CI and Docker to, basically, automate my own job.

We are using GitLab CI to build Docker containers in which GitLab CI can be used to run Ansible to automatically update servers following the editing of the users YAML dictionary configuration files, so you can define users as the following example shows, using the GitLab IDE to edit the file using your web browser, the configuration is saved in a git repo and then checked (I’m working on this aspect at the moment, it isn’t good having mistakes in a YAML file break a server!) and if it passes applied to the server, when you click save.

---
users:
  wp:
    users_name: WordPress
    users_email: chris@webarch.net
    users_ssh_public_keys:
      - https://git.coop/chris.keys
    users_quota: 2G
    users_mariadb_databases:
      - wp_live
      - wp_dev
    users_phpfpm_pm: dynamic
    users_phpfpm_max_children: 4
    users_phpfpm_pm_start_servers: 2
    users_apache_virtual_hosts:
      live/web:
        users_apache_server_name: www.wp.wsh.webarchitects.org.uk
        users_apache_server_aliases:
          - wp.wsh.webarchitects.org.uk
        users_apache_type: php
        users_cms: wordpress
        wordpress_dbname: wp_live
        wordpress_url: https://www.wp.wsh.webarchitects.org.uk
        wordpress_title: "WordPress Blog"
        wordpress_admin_user: chris
        wordpress_admin_email: chris@webarch.coop
        users_apache_nophp_dirs:
          - wp-content/uploads
        users_apache_locations:
          - authname: WordPress Admin
            location: /wp-login.php
        users_apache_htauth_users:
          - name: wp
            password: admin
      dev/web:
        users_apache_server_name: www.dev.wp.wsh.webarchitects.org.uk
        users_apache_server_aliases:
          - dev.wp.wsh.webarchitects.org.uk
        users_apache_type: php
        users_apache_robots: deny
        users_cms: wordpress
        wordpress_dbname: wp_dev
        users_apache_nophp_dirs:
          - wp-content/uploads
        users_daily_scripts:
          - "wp-update {{ users_basedir }}/wp/{{ users_sites_dir }}/dev/web"  # Update WordPress nightly
        users_apache_locations:
          - authname: WordPress Development Site 
            location: /
        users_apache_htauth_users:
          - name: wp
            password: admin
...

Another key thing that our server configuration does is chroot php-fpm and sshd to ensure that users cannot reach others users data (I need to also look at doing this for mysql), in addition everything apart from directories for sockets and users home directories is a read-only, bind mounted Debian install with no configuration other than the entries for users in /etc/passwd and /etc/group.

We also have automated installation of WordPress, Matomo (giving each user an account and adding their sites and configuring the WordPress plugin) and phpMyAdmin (again giving all users web based access to manage their databases) and intend to add some others.

Documenting everything has still to be done but the nice thing about Ansible is that it is generally so readable that it documents itself.

For sharing SSH keys the easiest thing is to add them to GitHub and / or Launchpad, eg:

Then on a server you can do apt install ssh-import-id -y && ssh-import-id chriscroome to add your keys.

However when I script the installation of keys I generally use this URL as it is nicer and under our control:

Thanks :slight_smile: I get what you’re saying, but us geeks have had decades to make the web-of-trust work. We’ve failed immensely. Now, someone has built infra that’s coaxed it into use, with minimal lock-in, amongst the ranks of an astoundingly important grassroots nontechnical movement fighting for climate justice (XR).

imho we need to appreciate that and not avert our eyes or words. I respect what you’re saying, and probably agree on principles, but seemingly disagree on tactics. I humbly advocate, as general rule in situations like this: one should try it, use it (while not overly relying on it), and try to understand why it’s succeeding where we’ve failed <3

Ah, you’re right. Sorry Chris. I read this as asking about tools to help manage SSH user access, not just tools to add to the environment :disappointed:

This is amazing work Chris. Such an asset to the community! Nice one!

1 Like

To echo Chris, I always liked Debops, but they seemed really over engineered and hard to adapt. Like him I felt there needed to a slightly more simple alternative. And here Chris is to provide that.

I hope Chris’ playbooks have wider adoption outside the coop community to prove to the wider tech world that coops can ship good code - because we really can - people just don’t know it yet!

2 Likes