add --certkey

This commit is contained in:
ed 2026-04-22 20:32:18 +00:00
parent 43773f2c7e
commit 8c7cdf8583
6 changed files with 21 additions and 6 deletions

View file

@ -3127,9 +3127,10 @@ when generating hashes using `--ah-cli` for docker or systemd services, make sur
## https ## https
both HTTP and HTTPS are accepted by default, but letting a [reverse proxy](#reverse-proxy) handle the https/tls/ssl would be better (probably more secure by default) both HTTP and HTTPS are accepted by default, but please ignore copyparty's built-in https/tls support and instead use a [reverse proxy](#reverse-proxy) to handle https/tls/ssl
copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well -- but note that HTTP/1 is usually faster than both HTTP/2 and HTTP/3 * reverseproxies do a better job following [best practices](https://cipherlist.eu/) meaning they are more secure, and probably also have higher performance
* also, copyparty doesn't speak HTTP/2 or QUIC, so using a reverse proxy would solve that as well -- but note that HTTP/1 is usually faster than both HTTP/2 and HTTP/3
if [cfssl](https://github.com/cloudflare/cfssl/releases/latest) is installed, copyparty will automatically create a CA and server-cert on startup if [cfssl](https://github.com/cloudflare/cfssl/releases/latest) is installed, copyparty will automatically create a CA and server-cert on startup
* the certs are written to `--crt-dir` for distribution, see `--help` for the other `--crt` options * the certs are written to `--crt-dir` for distribution, see `--help` for the other `--crt` options
@ -3141,6 +3142,11 @@ to install cfssl on windows:
* rename them to `cfssl.exe`, `cfssljson.exe`, `cfssl-certinfo.exe` * rename them to `cfssl.exe`, `cfssljson.exe`, `cfssl-certinfo.exe`
* put them in PATH, for example inside `c:\windows\system32` * put them in PATH, for example inside `c:\windows\system32`
if you really wanna give copyparty an existing TLS certificate then do one of the following:
* `--no-crt --cert server.pem` where `server.pem` is a concatenation of key + cert + chain (in that order), or...
* `--no-crt --cert server.crt --certkey server.key` where `server.key` is the key, and `server.crt` is a concatenation of cert + chain (in that order)
* file-extensions don't matter, but all files are expected to be [PEM-style](https://github.com/9001/copyparty/blob/hovudstraum/copyparty/res/insecure.pem)
# recovering from crashes # recovering from crashes

View file

@ -1357,7 +1357,8 @@ def add_tls(ap, cert_path):
ap2 = ap.add_argument_group("SSL/TLS options") ap2 = ap.add_argument_group("SSL/TLS options")
ap2.add_argument("--http-only", action="store_true", help="disable ssl/tls -- force plaintext") ap2.add_argument("--http-only", action="store_true", help="disable ssl/tls -- force plaintext")
ap2.add_argument("--https-only", action="store_true", help="disable plaintext -- force tls") ap2.add_argument("--https-only", action="store_true", help="disable plaintext -- force tls")
ap2.add_argument("--cert", metavar="PATH", type=u, default=cert_path, help="path to file containing a concatenation of TLS key and certificate chain") ap2.add_argument("--cert", metavar="PATH", type=u, default=cert_path, help="path to file containing a concatenation of TLS key and certificate chain (if \033[33m--certkey\033[0m is not set), or just the certificate chain (if \033[33m--certkey\033[0m is set)")
ap2.add_argument("--certkey", metavar="PATH", type=u, default="", help="path to file containing just the certificate key; if this is set, then \033[33m--cert\033[0m should only contain the certificate chain")
ap2.add_argument("--ssl-ver", metavar="LIST", type=u, default="", help="set allowed ssl/tls versions; [\033[32mhelp\033[0m] shows available versions; default is what your python version considers safe") ap2.add_argument("--ssl-ver", metavar="LIST", type=u, default="", help="set allowed ssl/tls versions; [\033[32mhelp\033[0m] shows available versions; default is what your python version considers safe")
ap2.add_argument("--ciphers", metavar="LIST", type=u, default="", help="set allowed ssl/tls ciphers; [\033[32mhelp\033[0m] shows available ciphers") ap2.add_argument("--ciphers", metavar="LIST", type=u, default="", help="set allowed ssl/tls ciphers; [\033[32mhelp\033[0m] shows available ciphers")
ap2.add_argument("--ssl-dbg", action="store_true", help="dump some tls info") ap2.add_argument("--ssl-dbg", action="store_true", help="dump some tls info")

View file

@ -51,9 +51,12 @@ def ensure_cert(log: "RootLogger", args) -> None:
with open(args.cert, "wb") as f: with open(args.cert, "wb") as f:
f.write(cert_insec) f.write(cert_insec)
if args.certkey and not os.path.isfile(args.certkey):
raise Exception("certificate-key file does not exist: " + args.certkey)
with open(args.cert, "rb") as f: with open(args.cert, "rb") as f:
buf = f.read() buf = f.read()
o1 = buf.find(b" PRIVATE KEY-") o1 = buf.find(b" PRIVATE KEY-") if not args.certkey else 0
o2 = buf.find(b" CERTIFICATE-") o2 = buf.find(b" CERTIFICATE-")
m = "unsupported certificate format: " m = "unsupported certificate format: "
if o1 < 0: if o1 < 0:
@ -252,7 +255,7 @@ def gencert(log: "RootLogger", args, netdevs: dict[str, Netdev]):
if args.http_only: if args.http_only:
return return
if args.no_crt or not HAVE_CFSSL: if args.no_crt or args.certkey or not HAVE_CFSSL:
ensure_cert(log, args) ensure_cert(log, args)
return return

View file

@ -616,6 +616,8 @@ class Ftpd(object):
print(t.format(pybin)) print(t.format(pybin))
sys.exit(1) sys.exit(1)
if self.args.certkey:
h1.keyfile = self.args.certkey
h1.certfile = self.args.cert h1.certfile = self.args.cert
h1.tls_control_required = True h1.tls_control_required = True
h1.tls_data_required = True h1.tls_data_required = True

View file

@ -157,7 +157,7 @@ class HttpConn(object):
try: try:
assert ssl # type: ignore # !rm assert ssl # type: ignore # !rm
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ctx.load_cert_chain(self.args.cert) ctx.load_cert_chain(self.args.cert, self.args.certkey)
if self.args.ssl_ver: if self.args.ssl_ver:
ctx.options &= ~self.args.ssl_flags_en ctx.options &= ~self.args.ssl_flags_en
ctx.options |= self.args.ssl_flags_de ctx.options |= self.args.ssl_flags_de

View file

@ -1232,6 +1232,9 @@ class SvcHub(object):
for x in [x.split(" ") for x in al.sftp_key or []] for x in [x.split(" ") for x in al.sftp_key or []]
} }
if not al.certkey:
al.certkey = None
mte = ODict.fromkeys(DEF_MTE.split(","), True) mte = ODict.fromkeys(DEF_MTE.split(","), True)
al.mte = odfusion(mte, al.mte) al.mte = odfusion(mte, al.mte)