553 Could not create file
Responses
Just because they share a name doesn't mean they're the same thing. The "root" user and "root" group are two very different things.
If a directory's ownership is root:root and the directory's permissions are set to mode 755 (rwxr-xr-x), the "userx" user, even if a member of the "root" group, is not going to be able to write to the directory. You'd need to either:
- change the directory's permissions to 775 (rwxrwxr-x)
- set an ACL on the directory that either explicitly gives the "userx" user write permissions to the directory or gives all members of group "root" write permissions to that directory.
Separate from the above, depending which FTP service you're using and how that FTP service is configured, "userx" may be getting mapped (to a security context) differently within the FTP service context than it does from an interactive shell.
Did you try some simple tests such as an ftp to the userx home directory or to /tmp? If you can't 'write' files to either of those locations it may not be a permission problem at all so much as an ftp configuration problem.
Have you looked at the config files in /etc/vsftpd, especially vsftpd.conf? Entries such as write_enable, etc?
Is SELinux enabled? Run the following:
# getenforce
If it is, you will need to update a few booleans, and you may have to create a new policy (due to using that non-standard directory for your share). I don't believe there is a similar Windows functionality to compare to, unfortunately. I guess SElinux is sort of similar to the User Access Control, whereas if you try to do something that is tecnically possible, it will stop you for further validation. In this case, the validation is a bit more involved than putting in the Administrator password ;-)
Unfortunately the only page I could find specific to SElinux is external to Red Hat.
http://linux.die.net/man/8/ftpd_selinux
Great idea to check for SELinux. Have you looked in the /var/log/messages file for any errors when you're trying to ftp?
You can do a "tail -F /var/log/messages" in one window to watch the messages log "live" and then try your ftp tests (successful and unsuccessful) from another window. Do you see any interesting output from the messages log when the ftp's fail?
The next logical step is to run the following command:
setenforce 0
This put SELinux into 'permissive' mode. Try FTPing after that. If it works, we gotta sort out your SELinux! I don't imagine the FTP Daemon can write to that directory you mentioned under SELinux defaults.
So - that basically means that the UAC is enabled. Now - SElinux is no trivial thing to review.
However (and this is a good "troubleshooting measure") you can temporarily disable SElinux, by doing the following
# setenforce 0
You may find people recommending that you change the value in /etc/sysconfig/selinux and reboot, which works - however... and I stress... if you go that route and decide to enable SElinux again, the system has to reapply all of the file context/rules which can take a while.
Also - you can follow what is going on by reviewing /var/log/audit/audit.log - a beautiful thing with the Linux shell is the ability to follow the log as it is being written.
So, I recommend - open 2 termina windows (at least - as the tail -f will consume the window it is run in)
# setenforce 0
# tail -f /var/log/audit/audit.log
-- then, attempt to ftp to your system and watch the terminal with the tail -f in it.
Try this five step approach now:
1. Find out which package provides the utility we need:
yum provides "*bin/semanage"
2. Install that package:
yum install policycoreutils-python
3. Find out what kind of security contexts were applicable to the usual location:
semanage fcontext --list | grep --color 'var/ftp'
A note here: The audit.log file mentioned by James above is a better indicator of which policy was keeping you. But to fall in-line with best practices or the usual, just take it from a well-known directory on the file system.
4. Add the policy to the system:
semanage fcontext --add --type public_content_t "/opt/installs(/.*)?"
5. Apply the policy:
restorecon -r /opt/installs
6. Enable SELinux:
setenforce 1
man ftpd_selinux
Should tell you a lot more information about how SELinux is controlling ftpd.
Which directory are you trying to use.
man ftpd_selinux
...
If you want to determine whether ftpd can login to local users and can
read and write all files on the system, governed by DAC, you must turn
on the ftpd_full_access boolean. Disabled by default.
setsebool -P ftpd_full_access 1
...
If you want to determine whether ftpd can read and write files in user
home directories, you must turn on the ftp_home_dir boolean. Disabled
by default.
setsebool -P ftp_home_dir 1
If you only want to allow ftpd to write to a particular directory we can set a label for this.
Any turning on one of the booleans would be better then running in permissive mode.
yes.. UAC is exactly that.. but, and this is a good example, it -could- potentially save your behind from malicious stuff. Like I mentioned previously, SElinux is by no means trivial. So, don't be discouraged that it made your life difficult.
To answer your question: permissive is certainly not the end of the world, and there is obviously a reason you can turn it off. In a nutshell SElinux prevents us (users/admins) from allowing certain files/ports from being used incorrectly. (I.e. you could not share your /etc via nfs, without putting some serious effort into making it work).
One thing to note about SElinux also. Generally there is already a rule to accomplish what you are trying to do, but.. you have to do it the way SElinux expects. So, if you were make your FTP share use the default location, you would not know that SElinux was enabled. The same goes with HTTP. If you use /var/www/html - then everything works. Else, you have to adjust rules.
Clear as mud? ;-)
I would agree with Daniel and the response Dhruv Ahuja posted is a detailed approach that I would consider a best practice.
Welcome to Linux! ;-)
Downside is it becomes a lot easier for the system to get thoroughly-owned (under SEL, a given context might get rifled, but the rifling is contained). That said, depending on how remote access to the system is governed, that may essentially be a non-risk (e.g., if you're running on a private network or have network access rules that only permit access from trusted hosts).
The thing to realize about SELinux is that it is a labeling system, every process and every file/directory has labels on it, and the Kernel has rules about the way process labeles interact with file/directory labels, as well as other process labels. We attempt to write these rules in the most common ways a user uses the confined process. SELinux would then prevent a hacked process (vsftpd) from doing anything on your system then be an ftp server. IE It could not be able to steal credit card data out of a database or read you secrets in your home directory. But the problem is if you change the default way the system works you need to tell SELinux about it.
Lets look at the AVC message you recieved
type=AVC msg=audit(1360854149.099:59129): avc: denied { write } for pid=4513 comm="vsftpd" name="installs" dev=dm-0 ino=2229328 scontext=system_u:system_r:ftpd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:usr_t:s0 tclass=dir
This avc says that the vsftpd (labeled as ftpd_t) program tried to write to the installs directory.
usr_t is the default labels of content under /usr and /srv. Out of the box we do not expect confined services to write to those directories, so it is blocked. As a matter of fact since most people setup ftp servers to only to share data, we block ftp server from writing to almost everything. With SELinux you have three options for this type of problem.
1. You could set labels like public_content_rw_t on the installs directory.
Setup default label for the /src/installs directory. SELinux uses regex for labels, so this says label everything under /src/installs including the installs directory as public_content_rw_t.
# semanage fcontext -a -t public_content_rw_t '/src/installs(/.*)?'
The semanage command tells SElinux to change the default labels, restorecon actually puts the default labels on files.
# restorecon -R -v /src/installs
Then you can set the SELinux boolean to allow ftpd servers to write to public_content_rw_t files/directories.
# setsebool -P allow_ftpd_anon_write 1
2. A second option would be to turn on a bigger SELinux boolean that would allow ftpd to read and write any file label on your system
# setsebool -P ftpd_full_access 1
This boolean effectively allows a hacked ftp server to be able to take over your system, but at least the rest of the confined processes would be controled.
3. You can also add your own custom rules to policy by using a tool called audit2allow which will translate the AVC messages into allow rules.
# grep ftpd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp
You can read more about SELinux on my blog.
http://danwalsh.livejournal.com/
Especially read up on some of the concepts I have brought forth here.
http://danwalsh.livejournal.com/30837.html
Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.
