I want to test my website in the real server, and I’m about to deploy it now. I was wondering about security issues, should I upload the files (via sftp) to /var/www/site/public_html as root, or should I create a user for the upload, and set the directory permissions to that user?
Thanks
Although you have accepted an answer here, the information provided is very wrong.
I appreciate that you will already know some of the things I'm going to say here, but since you accepted a very misleading answer there are some gaps in your understanding. Also not everyone reading this may have the same knowledge you do.
Yes, you should be careful with the root account and only use it where you have to. Only use it as it is intended to be used.
What you need is for the files to be readable by the webserver. And on a correctly configured device the webserver does not run as root. If you were to run
ps auxw | grep httpd
or
ps auxw | grep nginx
You would see at least 2 processes running. And actually one of them probably will be owned as root. That's because on the root user can start up a listening socket on a port number below 1024. That's a security thing. But having started the socket, this instance of the webserver then starts another instance of itself (running as a non-privileged user) to actually process requests.
On the box in front of me, I see....
root 20784 0.0 0.0 125116 1552 ? Ss 00:43 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 20785 0.0 0.0 125476 3252 ? S 00:43 0:00 nginx: worker process
www-data 20786 0.0 0.0 125476 3252 ? S 00:43 0:00 nginx: worker process
www-data 20787 0.0 0.0 125476 3252 ? S 00:43 0:00 nginx: worker process
www-data 20788 0.0 0.0 125476 3252 ? S 00:43 0:00 nginx: worker process
root 22579 0.0 0.0 14224 968 pts/1 SN+ 00:43 0:00 grep --color=auto nginx
So your content files need to be readable by the www-data user.
This account has even less privileges than the other account you describe. You can't login with this username. It is the opposite of the root account, it's a system or service account.
So how do you ensure you have the right permissions? You should have a regular account on the target you use to login (if you can ssh in or scp/sftp using the root account then your security is bad and should be fixed). Let's call this account auser. Once you have a shell on the system, then you should have the ability to become root via 'su' or 'sudo'. You can also transfer files using this account via sftp and scp (because you know that ftp is bad and have made sure there is no ftp server running on your host).
But this normal user account won't have permission to write to the directory containing the content (usually /var/www/html). So your first step in setting up the permissions is to change the ownership of this file to auser - and only root can do that. So...
sudo chown -R auser /var/www/html
Now /var/www/html should look something like this....
drwxr-xr-x 14 auser root 4096 Apr 5 19:52 /var/www/html
Looking at that first string of letters, the d means it is a directory, the rwx are the permissions for the owning user (read write and execute - but execute means something a bit weird for a directory - if a user should have any access to the directory then they need the execute permission). The first r-x indicates that the group has read and execute but not write. The second r-x means that every other account on the system (including www-data) has read and execute permissions on the directory.
The usual config for PHP, Python and Perl are that these are run as the webserver user (www-data). They do not need the executable permission bit set because they are not binaries (it would be required for pre-compiled languages like C and Go). There are models where the active content runs as different user than the webserver exist but are very rare and do not apply to your case.
But the default configuration on most Linux systems is to create files as ?rwx???--- (where the '?' represents stuff we're not that interested in. i.e. the "all other users" (or just "other" for short) don't get any permissions. And www-data can't read your files or cd into your directories. You could make sure you run....
chmod -R go+r /var/www/html
find /var/www/html -type d -exec chmod go+x {} \;
to fix this, but it's easier to just amend the config of your sshd to set the permissions appropriately. Typically you should be looking for the sftpserver definition in /etc/ssh/sshd_config and append '-u 002':
Subsystem sftp /usr/lib/openssh/sftp-server -u 002
Subsequently all transferred files will be -rw?rw?r-- and directories will be drwxrwxr-x
Yes, you could transfer the files as root / have the files owned by root and that does not compromise the security of your host. But allowing root to connect over ssh does compromise the security. That's why your sshd requires you to explicitly permit this to allow for edge cases - your sshd_config should contain...
PermitRootLogin No
Things get slightly more complicated when you need to allow multiple users to manage files. But we don't need to cover that now.
You will see mention on the the internet of chmod 0777
which gives everyone all permissions - never ever do this. Permissions are there to allow you to selectively share access.
So....
the root account is used to setup the initial permissions for a normal login account to control the files.
The webserver user should only have enough permissions to serve up the content (read-only).
Use a normal user account for managing files.