summaryrefslogtreecommitdiff
path: root/README.md
blob: 32b2c5c28b4d93a1a97824c1739ab4bc37baba9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# ngus

*ngus* is a minimalist HTTP server written in pure Python and intended for
receiving file uploads


## Discontinued

**Note:** *ngus* has been discontinued for the following reasons:

- the removal of the *cgi* module in Python >= 3.13,
making it difficult to handle multipart requests without additional
libraries / packages.

- the arrival of [miniserve](https://github.com/svenstaro/miniserve)
that seems to satisfy the criteria described bellow.


## Motivation

The reason for writing this small package was the need to transfer files from
a Windows desktop machine running on a highly restricted VPN to my GNU and UNIX
systems.

Since the HTTP traffic (out) was not restricted, I started looking for a small
, yet flexible HTTP server that could satisfy the following criteria:

- can be configured with the help of a few CLI parameters

- can be started and stopped quickly by an unprivileged user

- be able to receive uploads to a specific directory

- be portable and require a minimal amount of dependencies

- be part of the C/C++ or Python ecosystems

To my amazement I wasn't able to find any free software matching that criteria.


## Overview

The main purpose of *ngus* is to accept file uploads as POST requests from an
HTTP client.

Currently *ngus* provides only simple encryption (HTTPS) support. Many
different tools can be employed to serve as an HTTPS proxy.

See the examples bellow for more details!


## Installation

### pip (pypi)

   ```bash
   pip install ngus
   ```


### Gentoo

   ```bash
   # add sgs' custom repository using app-eselect/eselect-repository
   eselect repository add sgs

   emerge www-servers/ngus
   ```


## Examples

When installing *ngus* as described above, a dedicated *ngus* script
(entry point) will be installed in addition to the *ngus* Python module.

Running:

   ```bash
   ngus -h
   ```

will be for all practical purposes the same as running:

   ```bash
   python -m ngus -h
   ```

The latter format will be used for the rest of this section.


   ```bash
   python -m ngus -H 0.0.0.0 -p 8080
   ```

will start the server, binding port 8080 on all available interfaces and
storing the received uploads in the current working directory (CWD), while

   ```bash
   python -m ngus -H 0.0.0.0 -p 8080 -u /home/s/uploads
   ```

will store them in `/home/s/uploads`

**Note:** This will allow *ngus* to replace any existing file in this directory.

Once the server is running a client will be able to send a POST form with a
file data. One can always access the URL (send a GET request) with a regular
browser and use the provided form or simply use a client like *curl* for
posting (sending a POST request) a form.

   ```bash
   curl -F "ufile=@myfile.zip" http://158.39.125.240:8080
   ```

The default form input field name is *ufile*. That can be changed by using the
*--input-name* parameter. Basic auth support can be added with the
*--basic-auth* parameter.

   ```bash
   python -m ngus -H 0.0.0.0 -p 8080 -i uploadfile -b "uname:foo" -u /home/s/uploads
   curl --basic -u uname -F "uploadfile=@myfile.zip" http://158.39.125.240:8080
   ```

Simple encryption (HTTPS) support

   ```bash
   # creating a self-signed key / certificate pair valid for 356 days
   openssl req -sha256 -newkey rsa:4096 -nodes -x509 -extensions v3_ca -subj "/C=NO/O=MyOrg/CN=uploads.myhostname.net" -days 365 -keyout uploads.myhostname.net.key.pem -out uploads.myhostname.net.cert.pem
   python -m ngus -H 0.0.0.0 -p 8080 -b "uname:foo" -k uploads.myhostname.net.key.pem -c uploads.myhostname.net.cert.pem -u /home/s/uploads
   # since the certificate is self-signed, it can serve as a CA to itself in this example
   curl --basic -u uname -F "ufile=@myfile.zip" --cacert uploads.myhostname.net.cert.pem https://uploads.myhostname.net:8080
   ```


### Using *nginx* as a proxy

*ngus* will usually not be run on ports 80 (HTTP) and 443 (HTTPS) since binding
them requires administrator (root) privileges.

Running *ngus* on a unprivileged port (> 1024) may not solve the problem
described above. Namely a potential client may not be able to communicate to
ports other than 80 and 443 because of imposed firewall / VPN restrictions.

Another potential challenge arises when *ngus* runs on a host that is not
publicly accessible.

*nginx* can be used to proxy the traffic toward *ngus* instance running as
described in the examples above.

   ```nginx
   server {

      listen 443 ssl;
      listen 80;
      server_name uploads.myhostname.net;

      access_log /var/log/nginx/uploads.myhostname.net.access.log;
      error_log /var/log/nginx/uploads.myhostname.net.error.log error;

      ssl_certificate uploads.myhostname.net.cert.pem;
      ssl_certificate_key uploads.myhostname.net.key.pem;

      location / {
          # point at the ngus instance running on a private network address
          proxy_pass http://158.39.125.240:8080/;
      }

   }
   ```

... and then upload a file with:

   ```bash
   curl -F "ufile=@myfile.zip" https://uploads.myhostname.net
   ```


## Support and contributing

ngus is hosted on GitHub: https://github.com/blackm0re/ngus


## Author

Simeon Simeonov - sgs @ LiberaChat


## [License](https://github.com/blackm0re/ngus/blob/master/LICENSE)

Copyright (c) 2021-2023 Simeon Simeonov
All rights reserved.

[Licensed](https://github.com/blackm0re/ngus/blob/master/LICENSE) under the
GNU General Public License v3.0 or later.
SPDX-License-Identifier: GPL-3.0-or-later