Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

apache - Block file overwrite with Apache2 WebDAV

I am setting up an internal server that will permit anonymous file uploads to a specific directory with HTTP. Note that I'm trying to avoid implementing something that is based on Python, PHP, etc to keep this setup as simple as possible, as I may not be the one that ultimately supports this system in the future.

I have a basic setup working using Apache2's WebDAV module, but I also want to block overwrites of any files that currently exist. Does WebDAV have an extension for this?

Here is my current configuration script:

### Base HTML Directory
DIR_BASE=/var/www/html
mkdir -p $DIR_BASE
# Ownership
find $DIR_BASE -type f -exec chown root:apache {} ;
find $DIR_BASE -type d -exec chown root:apache {} ;
# Permission
find $DIR_BASE -type f -exec chmod 0644 {} ;
find $DIR_BASE -type d -exec chmod 0755 {} ;
# SELinux - Allow Apache to serve contents
chcon -t httpd_sys_content_t $DIR_BASE -Rv
### Upload HTML Directory
DIR_UPLOAD=/var/www/html/uploads
mkdir -p $DIR_UPLOAD
# Ownership
find $DIR_UPLOAD -type f -exec chown root:apache {} ;
find $DIR_UPLOAD -type d -exec chown root:apache {} ;
# Permission
find $DIR_UPLOAD -type f -exec chmod 0644 {} ;
find $DIR_UPLOAD -type d -exec chmod 0775 {} ;
# SELinux - Allow Apache to write to directory
chcon -u system_u -t httpd_sys_rw_content_t $DIR_UPLOAD -Rv
### Web Service
# Upload Section
#  <Directory "/var/www/html/uploads">
#    Options None # Don't allow any secondary features, such as listing the files
#    AllowOverride None # Don't allow overrides from other configuration files
#    Allow from all # Anonymous Access
#    Require all granted # Anonymous Access
#  </Directory>
#  <Location /uploads>
#    Dav On # WebDAV for file upload functionality
#    <LimitExcept PUT> # Limit to file upload only
#      Order Allow,Deny # Anonymous Access
#      Allow from all # Anonymous Access
#    </LimitExcept>
#  </Location>
cat > /etc/httpd/conf.d/uploads.conf << _EOF
Alias /uploads "/var/www/html/uploads"
  <Directory "/var/www/html/uploads">
    Options None
    AllowOverride None
    Allow from all
    Require all granted
  </Directory>
  <Location /uploads>
    Dav On
    <LimitExcept PUT>
      Order Allow,Deny
      Allow from all
    </LimitExcept>
  </Location>
_EOF
restorecon -vF /etc/httpd/conf.d/uploads.conf
systemctl enable httpd
systemctl restart httpd
### Firewall
firewall-cmd --add-service=http --permanent
firewall-cmd --reload

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I found my solution using the inotify-tools package. I had originally planned to use a simple cron job with batch processing, but with that package I could perform on-demand single-file processing. Given the relatively low volume of files I expect to receive, this should suit my needs well.

Everything is the same in my original script, but I have added the following:

### File Processing
PROCESSED=/data/processed
mkdir -p $PROCESSED
# Ownership
find $PROCESSED -type f -exec chown root:wheel {} ;
find $PROCESSED -type d -exec chown root:wheel {} ;
# Permission
find $PROCESSED -type f -exec chmod 0644 {} ;
find $PROCESSED -type d -exec chmod 0755 {} ;
# Bash Script
mkdir -p /root/scripts
cat > /root/scripts/uploadprocesser.sh << '_EOF'
#!/bin/bash

SOURCE=/var/www/html/uploads
PROCESSED=/data/processed

inotifywait -m -e create -e moved_to --format "%f" $SOURCE 
    | while read FILENAME
        do
            if [[ $FILENAME != ".davfs.tmp"* ]]; then
                echo "Detected $FILENAME, moving"
                mv --backup=numbered "$SOURCE/$FILENAME" "$PROCESSED/$FILENAME"
            fi
        done
_EOF
chmod +x /root/scripts/uploadprocesser.sh
# Systemd Service
cat > /etc/systemd/system/uploadprocesser.service << _EOF
[Unit]
Description=File Upload Processing Service
After=httpd.service
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/bin/bash /root/scripts/uploadprocesser.sh

[Install]
WantedBy=multi-user.target
_EOF
systemctl daemon-reload
systemctl enable uploadprocesser
systemctl restart uploadprocesser

And since mv includes a built-in file rotation system, it negated the need for me to block overwrites. The comment from PMF got me thinking along these lines, so thanks for that!

[root@localhost ~]# ls /var/www/html/uploads/
lost+found

[root@localhost ~]# ls /data/processed/
test1  test1.~1~  test1.~2~  test1.~3~  test1.~4~  test1.~5~

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...