Accessing user files from a perl webserver - linux

I have a perl server which needs the ability to read user's files and data, and write to them. The users are authenticated via LDAP, so I can verify passwords and learn their home directory.
From here I need some way for this webserver (running as www-data) to access their files. I've thought about running every command through su/sudo but that's really not optimal when I just need to open/write/close/glob files in their home directories.
Is there standard practice for this? I haven't been able to turn up anything so far.
Notes
I want the files in their home directory, as the users will be SSHing in and running other commands on them that won't be available via the web
The web connection is made over HTTPS of course.
Related
How to successfully run Perl script with setuid() when used as cgi-bin?

You might want to reconsider your architecture. This sounds like a job for virtual hosts in an ISP-like configuration.
First, read "Dynamically configured mass virtual hosting" page in the Apache VirtualHost documentation. Then read about how to run each virtual host as a different user
Under this approach you would have a vhost for each user running as $user.example.com; when Apache forks off a worker for the vhost, the fork runs suid as the appropriate user. Then you set up docroot and scriptalias for the vhost which point to the site code.
Long story short, it's probably better to use Apache's (well-tested and well-documented) features for managing user identity than it is to do it in Perl or whip up your own suid wrapper. It's notoriously difficult to get it right.

Are you running Apache? This sounds like a job for WebDAV.
The trouble is that your web server is running as www-data. By design, it won't be able to change the owner of any file. Some other privileged process will need to change ownership on the webserver's behalf.
You could write a minimal set UID script to handle changing the ownership of files and deleting them, but this path is fraught with peril (especially if you've never written a setUID program before.)

Related

How to securely host file on RHEL server and enable download for user

I have programmed an application that users can use to process genome data. This application relies on a 10GB database file, that users have to download in order to run the application. At the moment, I have stored this file on Google Drive, but the download bandwith is limited, so if a number of users download the file on a certain day, it will not work for others and they will get errors running the application.
My solution would be to host the file on our research server, create a user that only has access rights to this folder and nothing else, and make the file downloadable from the server via scp within the application (which is open source) through that user.
My question now is, is this safe to do or are people potentially able to hack into our server? If this method would be a security risk, what would be a better way to provide this file?
Thank you in advance!
Aloha
You can setup something like free Seafile https://www.seafile.com/en/home/, or ask the admin to set it up for you which is pretty secure like a self hosted google drive with 2fa authentication.
Another nice and easy tool is Filebrowser on github (https://github.com/filebrowser/filebrowser)
I would not really advice giving people shell/scp access inside your network.
And hosting anything inside a company network is in general not wisest idea, there is a always a risk involved.
I would setup a Seafile/filebrowser solution at a cheap rented server outside your network and upload it there. Or if you have a small pc left set it up in a DMZ Zone, a zone that has special access restrictions inside your company.
You want to use SSH (scp) as a transportation and authentication method for file hosting. It's possible to keep this safe with caution. For example, GitHub uses SSH for transport when providing git access with the git+ssh protocol.
Now for the caution part, if you haven't done it before, it's not a trivial task.
The proper way to achieve this would be set up an isolated SSH server in a chroot environment, and set up an SSH user on this isolated SSH instance only (not a user in the system that is added by eg useradd). Then you can add the files that's absolutely necessary to the chroot, and provide SSH access to users.
(Nowadays you might want to consider using Linux filesystem namespaces, if applicable, to replace chroot, but I'm not sure on this.)
As for other options, setting up a simple Nginx server for static file hosting might be a lot easier, provided you have some understanding of HTTP and TLS. There're lots of writings on the Internet about this.
Both ways, if you are to expose your server to the Internet or Intranet, you need to make sure of firewalling. Consider to learn about nftables or firewalld or the like, if you haven't already.
SSH is reasonably safe. Always keep software up-to-date.
Set up an sftp-only user with chrooted directory. In /etc/ssh/sshd_config:
Match User MyUser
ChrootDirectory /var/ssh/chroot
ForceCommand internal-sftp
AllowTcpForwarding no
PermitTunnel no
X11Forwarding no
This user will not get a shell (because of internal-sftp), and cannot see files outside of /var/ssh/chroot.
Use a certificate client-side, additional to password.
Good description of the setup process for certificates:
https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server
Your solution is moderately safe.
A better solution is to put it on a server accessible via sftp, behind a password, but also encrypt the file: in this way you introduce a double layer of protection.
On a Linux server you should be able to use a tool like gpg to encrypt your file.
Next you share the decryption key with your partners using a secure channel with e.g. an end2end encrypted messaging software.

How to let users run arbitrary source code on my server

I want to automate testing of my users' source code files by letting them upload c++,python, lisp, scala, etc. files to my linux machine where a service will find them in a folder and then compile/run them to verify that they are correct. This server contains no important information about any of my users, so there's no database or anything for someone to hack. But I'm no security expert so I'm still worried about a user somehow finding a way to run arbitrary commands with root privileges (basically I don't have any idea what sorts of things can go wrong). Is there a safe way to do this?
They will. If you give someone the power to compile, it is very hard not to escalate to root. You say that server is not important to you, but what if someone sends you an email from that server, or alters some script, to obtain some info on your home machine or another server you use?
At least you need to strongly separate you from them. I would suggest linux containers, https://linuxcontainers.org/ they are trendy these days. But be careful, this is the kind of service that is always dangerous, no matter how much you protect yourself.
Read more about chroot command in Linux.
This way you can provide every running user program with separate isolated container.
You should under no circumstances allow a user to run code on your server with root privileges. A user could then just run rm –rf / and it would delete everything on your server.
I suggest you make a new local user / group that has very limited permissions, e.g. can only access one folder. So when you run the code on your server, you run it in that folder, and the user can not access anything else. After the code has finished you delete the content of the folder. You should also test this vigorously to check that they really cant destroy / manipulate anything.
If you're running on FreeBSD you could also look at Jails, which is sort-of a way of virtualization and limiting a user / program to that sandbox.

Can I use setuid or sticky to make a file created by PHP a certain user?

I'm using WordPress and I want files created by WordPress to have the user of the file that created them, not the user the web server is running as. For example, my WordPress files and directories are owned by philip in the group www-data. When WordPress creates a file, I want the owner of the file to be philip and not www-data.
Is this possible? My suspicion is it can be achieve with setuid or sticky bit, but I'm not sure how to apply it.
Not without a lot of extra effort. From what you're describing, it sounds like you're probably running PHP using mod_php or something similar; that will always run within the web server, as the web server user. setuid/setgid only work when there's a new process being executed, which isn't the case here.
You can work around this by running PHP using CGI or FastCGI (which'll let you run all PHP scripts as your own user), but that's a lot of extra setup that you probably don't want to get into.
If you don't want the group to have access, you could use the sticky bit to set g-rwx. The problem with setgid (you asked to change the group, not the user), is that the user running the command must have privileges to assign that group. If you don't want the webserver (i.e. www-data) to have access, then you probably don't want to change the gid to any group that it has access to. Otherwise, you'll need to have some other process with other privileges come along and make this change for the web server, via cron or some other scheduler.

best approah (security) to do some admin work through web page in Linux?

I want to build a web based admin tools that allow the system admin to run pre-configured commands and scripts through a web page (simple and limited webmin), what is the best approach?
I already started with Ubuntu installing LAMP and give the user www-data root's privileges !!!
as I learned (please check the link) this is a really bad move !!!, so how to build such web-based system without the security risk?
cheers
I did something like this a couple of years ago. It was (I like think) fairly secure and only accessible to a limited number of pre-vetted, authenticated users, but it still left me with an uneasy feeling! If you can avoid doing it, I'd recommend you do :)
I had a database sitting between the frontend web-tier and the script which was actually executing actions. The relevant table contained a symbolic command name and an optional numeric argument, which was sufficient for my needs. This allows you to audit what's been executed, provides a quick and dirty way to have a non-www user do things, and means if the website is compromised they're constrained by the DB structure (somewhat) and the script which pulls data from it.
The data from the DB can be read by a daemon running in a separate, unprivileged account. The daemon pulls and sanitises data from the DB and maps the 'command' to an actual executable (with a hard-coded map, so commandA executes A, commandB executes foo, and anything else would get flagged as an error). The account can be locked down using AppArmor (or SELinux, I imagine) to prevent it from executing, reading or writing anything you don't expect it to. Have a system in place to alert you of any errors from either the daemon or AppArmor/SELinux.
The executables which the daemon runs can be setuid'd if appropriate, or you can use the sudoers mechanism to allow the unprivileged account to execute them without a password.
I already started with Ubuntu installing LAMP and give the user www-data root's privileges
Don't do this.
If you really want to execute some very specific scripts under root privileged. Create such predefined very limited scripts, allow their password-less execution with sudo for specific user and then run them via script and don't forget authentication.
Generally this is bad idea.
SSH is your best friend.

when should I use "apache:apache" or "nobody:nobody" on my web server files?

Background: I remember at my old place of employment how the web server admin would always make me change the httpd-accessible file upload directories so that they were owned by apache:apache or nobody:nobody.
He said this was for security reasons.
Question: Can you tell me what specifically were the security implications of this? Also is there a way to get apache to run as nobody:nobody, and are there security implications for that as well?
TIA
There is a valid reason, supposing the httpd (Apache) was owned by root and belongs to the group root also, and that there was a vulnerability that was found in the code itself, for example, a malicious user requested a URL that is longer than expected and the httpd seg-faulted. Now, that exploit has uncovered root access which means, it has control over the system and hence a malicious user would ultimately seize control and create havoc on the box.
That is a reason why the ownership of the httpd daemon runs under nobody:nobody or apache:apache. It is effectively a preventative measure to ensure that no exploit/vulnerability will expose root access. Imagine the security implications if that was to happen.
Fortunately, now, depending on the Linux distribution, BSD variants (OpenBSD/FreeBSD/NetBSD) or the commercial Unix variants, the httpd daemon runs under a user group that has the least privileges. And furthermore, it would be safe to say that a lot of the Apache code has been well tested enough and stable. About 49% of servers across all domains are running Apache. Microsoft's IIS runs at 29% of the domains. This is according the the netcraft survey site here.
In another context, it shows that having a program running under least privileges would be deemed 'safe' and mitigates any possible chances of exploits, vulnerabilites.
This is the wrong site for this question. Ordinarily you would not want the source code to be owned by the same user as Apache. Should a security flaw in Apache or your server-side scripts arise, an attacker could maliciously modify your web site's files without privilege escalation.
The one exception would be file upload directories, as you said. In this case, you want Apache to make changes to that directory.

Resources