Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SSL to streams #3789

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open

Conversation

jbowring
Copy link

@jbowring jbowring commented Jun 2, 2024

Support for SSL for streams with TCP forwarding enabled. Uses the same web interface as creating a new Proxy Host for adding SSL.

Screenshot 2024-06-02 at 20 38 48 image

Details

An Nginx stream config created with this SSL feature looks like this:

# ------------------------------------------------------------
# 1883 TCP: 1 UDP: 1
# ------------------------------------------------------------

server {
  listen 1883 ssl;
  listen [::]:1883 ssl;

  # Let's Encrypt SSL
  include conf.d/include/ssl-cache-stream.conf;
  include conf.d/include/ssl-ciphers.conf;
  ssl_certificate /etc/letsencrypt/live/npm-9/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/npm-9/privkey.pem;

  proxy_pass google.com:443;

  # Custom
  include /data/nginx/custom/server_stream[.]conf;
  include /data/nginx/custom/server_stream_tcp[.]conf;
}

server {
  listen 1883 udp;
  listen [::]:1883 udp;

  proxy_pass google.com:443;

  # Custom
  include /data/nginx/custom/server_stream[.]conf;
  include /data/nginx/custom/server_stream_udp[.]conf;
}

Nginx doesn't allow stream and http blocks to share an SSL cache, so all streams have a separate SSL cache defined in ssl-cache-stream.conf:

ssl_session_cache shared:SSL_stream:50m;

Use a DNS Challenge is forced as streams cannot perform HTTP authentication for issuing certificates.

Streams do not have domain names associated with them in the database or displayed in the UI, as streams are not proxied by hostname but exclusively by port.

@jbowring
Copy link
Author

jbowring commented Jun 3, 2024

Related: #3368 #2542 #1829 #795

@RobertPosluszny
Copy link

RobertPosluszny commented Jun 17, 2024

I tested this using my custom SSL certificate running RTMPS from OBS and Zoom to RTMP for Owncast and it worked great! Zoom showed enhanced security because of RTMPS and SSL. The only issue I ran into is if I edited a stream (in the NPM GUI) it would default back to the default stream config template and remove the new SSL information. So I had to delete the stream and add it again and make sure not to edit it. But works perfectly fine if you don't edit a stream after creating it.

Edit: Resolved in 207dbb2

@RobertPosluszny
Copy link

@jbowring Do you have plans to update this PR with future releases?

@jbowring
Copy link
Author

@RobertPosluszny thanks for testing this PR and your feedback. I think I've found the issue you described and fixed it, please check and let me know!

I'll do some more testing myself and then update this PR with a pull from the develop branch.

@jbowring
Copy link
Author

@jc21 what else needs to be done before this PR can be merged? Thanks.

@RobertPosluszny
Copy link

@jbowring looks like the issue of editing stream settings after creation was resolved! Thanks!

@nginxproxymanagerci
Copy link

Docker Image for build 5 is available on DockerHub as jc21/nginx-proxy-manager:github-pr-3789

Note: ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.

@JanzenJohn
Copy link

JanzenJohn commented Sep 29, 2024

When testing the linked CI image the following error is shown in the browser console when trying to create a stream

TypeError: e[t] is undefined
    r https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:1
    190 https://MY-DOMAIN/js/14.bundle.14.js?v=2.11.3:1
    190 https://MY-DOMAIN/js/14.bundle.14.js?v=2.11.3:1
    r https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:1
    showNginxStreamForm https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    promise callback*showNginxStreamForm https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    action https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    click ui.action@https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    dispatch https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    handle https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    add https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    xe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    each https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:16
    each https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:16
    xe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    on https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegate https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegateEvents https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegateEvents https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    setElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    setElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    _ensureElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    View https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    constructor https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    i https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showEmpty https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    onRender https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    promise callback*onRender https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    O https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    render https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    ae https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    show https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showChildView https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showAppContent https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:310
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    promise callback*showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    Ze https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    i https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    s https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
[main.bundle.js:1:1930](https://MY-DOMAIN/js/main.bundle.js?v=2.11.3)
    oe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:1
    (Async: promise callback)
    showNginxStreamForm https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    action https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    click @ui.action https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    dispatch https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    handle https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    (Async: EventListener.handleEvent)
    add https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    xe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    each https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:16
    each https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:16
    xe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    on https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegate https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegateEvents https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegateEvents https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    setElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    setElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    _ensureElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    View https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    constructor https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    i https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showEmpty https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    onRender https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    (Async: promise callback)
    onRender https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    O https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    render https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    ae https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    show https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showChildView https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showAppContent https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:310
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    (Async: promise callback)
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    Ze https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    i https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    s https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
Uncaught (in promise) TypeError: e[t] is undefined
    r https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:1
    190 https://MY-DOMAIN/js/14.bundle.14.js?v=2.11.3:1
    190 https://MY-DOMAIN/js/14.bundle.14.js?v=2.11.3:1
    r https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:1
    showNginxStreamForm https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    promise callback*showNginxStreamForm https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    action https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    click ui.action@https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    dispatch https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    handle https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    add https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    xe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    each https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:16
    each https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:16
    xe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    on https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegate https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegateEvents https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegateEvents https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    setElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    setElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    _ensureElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    View https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    constructor https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    i https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showEmpty https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    onRender https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    promise callback*onRender https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    O https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    render https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    ae https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    show https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showChildView https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showAppContent https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:310
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    promise callback*showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    Ze https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    i https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    s https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
[main.bundle.js:1:356](https://MY-DOMAIN/js/main.bundle.js?v=2.11.3)
    oe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:1
    (Async: promise callback)
    showNginxStreamForm https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    action https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    click @ui.action https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    dispatch https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    handle https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    (Async: EventListener.handleEvent)
    add https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    xe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    each https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:16
    each https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:16
    xe https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    on https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegate https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegateEvents https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    delegateEvents https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    setElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    setElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    _ensureElement https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    View https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    constructor https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    i https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showEmpty https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    onRender https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    (Async: promise callback)
    onRender https://MY-DOMAIN/js/9.bundle.9.js?v=2.11.3:1
    O https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    render https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    ae https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    show https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showChildView https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showAppContent https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:310
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    (Async: promise callback)
    showNginxStream https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:27
    Ze https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    i https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    s https://MY-DOMAIN/js/main.bundle.js?v=2.11.3:3
    

@RobertPosluszny
Copy link

@jbowring any way to update this PR to keep in line with the latest updates? Is there a way I can help keep that in line until this PR gets merged into develop or latest?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants