trBlueJ
trBlueJ

Reputation: 75

NGINX MKCOL fails with 405, error says mkdir() failed (17: File Exists)

I have an NGINX server running on OpenBSD 7.0 on an ARM64 architecture (that part shouldn't be an issue.) I'm trying to get it setup to accept WebDav requests PUT, MKCOL, DELETE, MOVE, and COPY. So far, the last three are working fine. I'm having an issue with MKCOL. I'd first like to note that I don't plan on using this with a WebDav client, I'm manually formulating the requests with curl right now, and will likely be automating the process later. When I execute

$ curl -nkfX MKCOL https://example.com/asd/

I get

curl: (22) The requested URL returned error: 405 Not Allowed

The NGINX error log shows

2021/12/06 17:19:04 [error] 8105#61261231328: *2563 mkdir() "/mnt/sd1c/documents" failed (17: File exists), client: [AN IP ADDRESS], server: example.com, request: "MKCOL /asd/ HTTP/1.1", host: "example.com"

I've also tried without the / at the end of the request URI. I've tried with URI /work/asd/ (with and without the /) where /work/ already exists in /mnt/sd1c/documents. /mnt/sd1c/documents is the root of the server.

I've also had an issue where it returns 404 with nothing in the error log. This error was fixed by changing the try_files $uri $uri/ =404; to try_files $uri $uri/ /; (which it currently is.) inside the location / block of the example.com file. I have no idea where the issue is here.

Here is the server configuration:

example.com

server {
    #listen 80;
    #listen [::]:80;

    # SSL configuration
    ###
    #
    listen 443 ssl;
    listen [::]:443 ssl;

    dav_methods off;
    dav_access user:rw group:rw all:r;

    include common;

    root /mnt/sd1c/documents;

    server_name example.com;

    ssl_client_certificate /var/www/ccrt/ca.crt;
    ssl_verify_client optional;

    index there_shouldnt_ever_be_a_file_called_this_so_yeah.html;

    location / {
        dav_methods PUT DELETE COPY MOVE MKCOL;
        autoindex on;
        autoindex_format xml;
        xslt_string_param path $uri;
        xslt_stylesheet /mnt/sd1c/www/example.com/internal/autoindex_format.xslt
            is_ssl_client_verify="$ssl_client_verify"
            val_remote_user="$remote_user";
        auth_basic $ssl_client_verify_auth;
        auth_basic_user_file /mnt/sd1c/www/example.com/passwd/documents;
        satisfy any;
        default_type text/plain;
        try_files $uri $uri/ /;
    }
}

common


set $cors_origin "";

if ($http_origin ~* "^https?://example.com$") {
    set $cors_origin $http_origin;
}

add_header Access-Control-Allow-Origin '$cors_origin';

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA HIGH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
charset utf8;

if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|COPY|MOVE|MKCOL)$ )
{
    return 405;
}

error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 500 501 502 503 504 505 506 507 508 510 511 444 494 495 496 497 300 301 302 303 304 307 /.i/error;

location /scripts {
    alias /mnt/sd1c/www/example.com/scripts;
    try_files $uri $uri/ $uri.js =404;
}

location /.i {
    alias /mnt/sd1c/www/example.com/internal;
    internal;
    try_files $uri $uri/ $uri.html =404;
    location ~ ^/.i/error(?:\.html)?$ {
        ssi on;
        auth_basic off;
        try_files $uri $uri/ $uri.html =404;
    }
}

location /style {
    alias /mnt/sd1c/www/example.com/style;
    try_files $uri $uri/ $uri.css =404;
}

location ~ /\.ht {
    deny all;
}

location /images {
    alias /mnt/sd1c/www/example.com/images;
    try_files $uri $uri/ $uri.png =404;
}

location ~ 418 {
    return 418;
}

my nginx.conf

#user nobody;
user www-data www-data;
worker_processes 1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}

http {
    client_body_temp_path /mnt/sd1c/client_body_tmp;
    include mime.types;
    default_type application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log main;
    server_names_hash_bucket_size 64;

    sendfile on;
    #tcp_nopush on;

    #keepalive_timeout 0;
    keepalive_timeout 65;


    include map;
    include http;
    include example.com;
}

map


map $request_uri $request_uri_path {
    "~^(?P<path>[^?]*?/?)/*(\?.*)?$" $path;
}

map $ssl_client_verify $ssl_client_verify_auth {
    SUCCESS off;
    default "Private Documents.";
}

map $status $status_text {
    400 'Bad Request';
    401 'Unauthorized';
    402 'Payment Required';
    403 'Forbidden';
    404 'Not Found';
    405 'Method Not Allowed';
    406 'Not Acceptable';
    407 'Proxy Authentication Required';
    408 'Request Timeout';
    409 'Conflict';
    410 'Gone';
    411 'Length Required';
    412 'Precondition Failed';
    413 'Payload Too Large';
    414 'URI Too Long';
    415 'Unsupported Media Type';
    416 'Range Not Satisfiable';
    417 'Expectation Failed';
    418 'I\'m a teapot';
    421 'Misdirected Request';
    422 'Unprocessable Entity';
    423 'Locked';
    424 'Failed Dependency';
    425 'Too Early';
    426 'Upgrade Required';
    428 'Precondition Required';
    429 'Too Many Requests';
    431 'Request Header Fields Too Large';
    451 'Unavailable For Legal Reasons';
    500 'Internal Server Error';
    501 'Not Implemented';
    502 'Bad Gateway';
    503 'Service Unavailable';
    504 'Gateway Timeout';
    505 'HTTP Version Not Supported';
    506 'Variant Also Negotiates';
    507 'Insufficient Storage';
    508 'Loop Detected';
    510 'Not Extended';
    511 'Network Authentication Required';
    300 'Multiple Choices';
    301 'Moved Permanently';
    302 'Found';
    303 'See Other';
    304 'Not Modified';
    305 'Use Proxy';
    306 'Switch Proxy';
    307 'Temporary Redirect';
    308 'Permanent Redirect';
    default 'Something went wrong.';
}

http

server_tokens off;

gzip  on;

client_body_buffer_size 1k;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;

add_header X-Frame_Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;

Upvotes: 1

Views: 2344

Answers (1)

trBlueJ
trBlueJ

Reputation: 75

Found what went wrong. By recompiling NGINX with the configure flag --with-debug, I found that the try_files $uri $uri/ / directive in the location / block is what causes the error. NGINX tries to match the try_files directive, and finds that / exists, so it tries to perform the MKCOL request with / instead of /asd/. Removing the try_files directive fixed this for me.

Upvotes: 1

Related Questions