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

Generating cert-file and key-file? #9

Closed
richb-hanover opened this issue Apr 9, 2022 · 18 comments
Closed

Generating cert-file and key-file? #9

richb-hanover opened this issue Apr 9, 2022 · 18 comments

Comments

@richb-hanover
Copy link

richb-hanover commented Apr 9, 2022

I would like to create a Dockerfile for the server side that I can run on a VPS out on the internet or a Raspberry Pi in my home. This would work like the Dockerfile that's in the Go RPM client repo to produce an easily-created server instance for testing.

To make the implementation easier, it would help for this repo to include the specification of the cert-file and the key-file required by networkqualityd. For example, the go implementation's README simply provides this information:

  -cert-file string
    	cert to use
  ...
  -key-file string
    	key to use
  • Would you provide sample information for creating the cert-file and the key-file? (What commands are necessary for creating them?)
  • These instructions should take into account I'll likely use a private 192.168.x.0/24 address for the implementation on my Raspberry Pi. No DNS name will be available; no external access available for verifying any certificates (such as Let's Encrypt).

Many thanks!

@afedotov
Copy link
Contributor

Hi, @richb-hanover!

If you want to run networkQuality tool (especially original version shipped with macOS) against any network-quality server, that server must provide valid SSL certificate with specific requirements:

  • it is not self-signed
  • it is signed with trusted CA
  • must use >= 2048 bits RSA keys
  • must use SHA-2 family signature algorithms
  • must include server DNS name in SAN extension, not only in subject CN
  • must include extendedKeyUsage=serverAuth extension
  • must have validity period of <= 825 days

These requirements described here - https://support.apple.com/en-us/HT210176

So in case you can't obtain trusted certificate from any available CA such as letsencrypt, e.g. you plan to setup your own network-quality server for internal use or development purposes, you must create such certificate yourself. That includes creating local CA certificate for signing and adding that CA certificate to macOS keychain as trusted certificate.

For convenience, you can use the following scripts that uses openssl shipped with macOS:

Steps are:

  1. Create root CA certificate:

    Root certificate key will be encrypted with password. Password provided via environment variable PASSWORD. If you prefer you can remove -passin and -passout parameters in script, then password will be asked from console. This password will be required each time you create server certificate signed by this CA.

    $ mkdir certs
    $ env PASSWORD=password ./create-root-CA.sh
    
  2. Add root CA to macOS keychain as trusted certificate:
    $ security add-trusted-cert -k login.keychain certs/dev-root-CA-crt.pem
    
  3. Create server certificates for each local server/IP you need:
    $ ./create-server-crt.sh localhost 127.0.0.1
    $ ./create-server-crt.sh router.asus.com 192.168.1.1
    

Key and certificate you need to provide in -key-file and -cert-file will be saved in the following files:

  • cert/HOSTNAME-key.pem
  • cert/HOSTNAME-crt.pem

@afedotov
Copy link
Contributor

BTW, do we really need SSL/TLS for network quality tests? SSL noticeably increases CPU usage. That's a big problem for small/embedded devices such as routers. Recently I've tried to run Go version of network-quality server on my ASUS router based on MIPS 32bit CPU. SSL computations on that device decreases network-quality server throughput by 10 or more times, so server is far behind ability to saturate network connection and unusable in such scenario.

Is it possible to add server/client option to run without SSL, is it prohibited by the specification? What about using UDP in addition to TCP/HTTP?

BTW, if you plan just to benchmark your private network using simple client/server tools, better look at https://github.com/udhos/goben, it is straightforward, implemented in Go and can use TCP or UDP and does not require SSL/TLS.

@richb-hanover
Copy link
Author

richb-hanover commented Apr 17, 2022

@afedotov Thanks for the link to your two scripts. I will take a look at how these might melded into a Docker container that runs the server. This will still be a challenge because of my desire to have a Dockerfile that can run at a generic IP address (public or private) where the other server config options (Apache, nginx) aren't available, but I now have something to play with.

@richb-hanover
Copy link
Author

@afedotov - you wrote:

BTW, do we really need SSL/TLS for network quality tests? SSL noticeably increases CPU usage.

Yes, I think so. A few thoughts:

  • It's in the RPM spec.
  • I am interested to measure the responsiveness/latency of the Wi-Fi link (not so much the transfer rates), and it doesn't look as if goben will do that.
  • Your point about saturating the CPU, not the network link is an important (critical) point. I had originally hoped to run the RPM server on my router: it might work on a beefy enough router. (It would be cool OpenWrt package, but we'd have to figure out how to inform people that they had a wimpy router, or interpret the results properly, or...)
  • I am now thinking about running the RPM server on something like a Raspberry Pi plugged into the wired network.
  • Finally, it would be useful if the macOS networkQualitybinary had a "--insecure" flag that allowed it to test against servers that didn't provide valid certificates. It would do all the SSL work, just ignore the errors. (This is a change in my opinion: in an discussion a few months ago, I had said that the client should "just work" either way. I now see that specifying a "--insecure" flag along with the configuration path is not a big burden.)

Thanks again

@afedotov
Copy link
Contributor

@richb-hanover - you wrote:

This will still be a challenge because of my desire to have a Dockerfile that can run at a generic IP address (public or private)

Pay attention to -extfile option of openssl x509 command. It adds subjectAltName and extendedKeyUsage X.509 extensions to the certificate. You can specify multiple DNS and IP records separating them by comma. Moreover you can specify wildcard for DNS names like *.yourdomain.com but not for IPs. So if you prefer to use plain IP addresses instead of DNS names you can either:

  • Provide exact list of allowed IP addresses
  • Use a trick with something like nip.io service.
    Issue certificate for *.nip.io domain, then use DNS names like 192-168-1-250.nip.io
  • Also you can setup your own private DNS which acts like nip.io

@afedotov
Copy link
Contributor

@richb-hanover - you wrote:

Your point about saturating the CPU, not the network link is an important (critical) point. I had originally hoped to run the RPM server on my router: it might work on a beefy enough router.

Yeah. Same thoughts about availability of RPM server right on the router. I've already tried that. To be honest I have not a fresh device. It is ASUS RT-N66U with single-core 32-bit Broadcom MIPS CPU and 1Gbps LAN / 450Mbps 802.11n:

system type             : Broadcom BCM5300 chip rev 1 pkg 0
processor               : 0
cpu model               : MIPS 74K V4.9
BogoMIPS                : 299.82
wait instruction        : no
microsecond timers      : yes
tlb_entries             : 64
extra interrupt vector  : no
hardware watchpoint     : yes
ASEs implemented        : mips16 dsp
shadow register sets    : 1
VCED exceptions         : not available
VCEI exceptions         : not available

Software server running directly on that router can't saturate network more than to 250Mbps using UDP protocol. With TCP saturation it is around 200Mbps. Tested with goben and simple HTTP server written in Go, serving virtually large file (same as RPM server doing it on /large endpoint). When adding SSL/TLS to the HTTP server, network saturation drops to the 25Mbps!!! Even tried different send chunk sizes, single or parallel connections, running client/server locally on the router via loopback interface, etc... Obviously RPi with ARM CPU is more powerful, I wonder how it will perform in such scenario. And what if you have 10Gbps network/router, I wonder if it can handle this.

@richb-hanover
Copy link
Author

Thanks for these suggestions and data points. I'll start to think about them when I return from holiday.

And what if you have 10Gbps network/router, I wonder if it can handle this.

Probably not (I believe an RPi has a gbit ethernet.) However, I'm most interested in examining Wi-Fi now.

Wi-Fi is the next frontier of "badly bloated home routers." SQM techniques (cake, fq_codel) have pretty much conquered bad responsiveness for dreadful ISP links varying from 3mbps DSL to normal cable and fiber speeds, and autorate is looking as if it can handle hour-to-hour (or even second-to-second) varying speeds on cable, cell phones, etc.

Thanks again.

@cpaasch
Copy link

cpaasch commented Apr 19, 2022

Regarding running without SSL/TLS:

One issue is that we rely on HTTP/2's multi-stream facility to measure latency on the load-generating connections. With HTTP/1 this is not possible. And, unfortunately there are not many HTTP/2 implementations that allow to run without TLS.

@richb-hanover
Copy link
Author

Regarding running without SSL/TLS:

I'm not suggesting that the client run the test without the HTTP/2. I simply want the test to proceed if the (otherwise well-formed) SSL info is self-signed when the --insecure flag is present.

@afedotov
Copy link
Contributor

I simply want the test to proceed if the (otherwise well-formed) SSL info is self-signed when the --insecure flag is present.

BTW, something similar is already committed to the Go client's main branch. However for now it is not an option and hardcoded to always skip verifying of insecure TLS certificates: network-quality/goresponsiveness@3b385ce

macOS shipped version of networkQuality doesn't have this feature, and it is not opensourced. Need to ask Apple developers to implement this.

@hawkinsw
Copy link
Member

Checking in from the client side to see if there is anything that I can do to help on this issue!

@hawkinsw
Copy link
Member

BTW, do we really need SSL/TLS for network quality tests? SSL noticeably increases CPU usage. That's a big problem for small/embedded devices such as routers. Recently I've tried to run Go version of network-quality server on my ASUS router based on MIPS 32bit CPU. SSL computations on that device decreases network-quality server throughput by 10 or more times, so server is far behind ability to saturate network connection and unusable in such scenario.

Is it possible to add server/client option to run without SSL, is it prohibited by the specification? What about using UDP in addition to TCP/HTTP?

BTW, if you plan just to benchmark your private network using simple client/server tools, better look at https://github.com/udhos/goben, it is straightforward, implemented in Go and can use TCP or UDP and does not require SSL/TLS.

@cpaasch @randall Just noting this message because we talked about it yesterday.

@richb-hanover
Copy link
Author

@cpaasch @randall I'm sorry I missed the meeting earlier this week. I still have questions about self-signed certificates.

I'm not suggesting that the client run the test without the HTTP/2. I simply want the test to proceed if the (otherwise well-formed) SSL info is self-signed (perhaps when a --insecure flag is present.)

  • Can the current macOS Monterey OS Version: Version 12.4 (Build 21F79) operate with a server that has a self-signed certificate?
  • Can the current iOS version also work with self-signed certificates?
  • If not, are there plans to do this?

Thanks.

@hawkinsw
Copy link
Member

hawkinsw commented Jul 1, 2022

@richb-hanover As you know, the client (by default) supports self-signed certs. Do you think that this should be optional and behind a flag?

@richb-hanover
Copy link
Author

I think the go-client works with self-signed cert's; do the macOS or iOS clients?

@hawkinsw
Copy link
Member

hawkinsw commented Jul 2, 2022

I think the go-client works with self-signed cert's; do the macOS or iOS clients?

That's correct. I was just asking whether the go-client should support it as an option. It currently always allows connections to servers with self-signed certs.

@richb-hanover
Copy link
Author

The go-client's behavior is correct (provide correct measurements, no matter who signs the certs).

An option is not warranted, nor do I believe it is even worth noting (in the output) that the server's certificate is self-signed.

This is network monitoring software, not credit card data. It's hard to imagine how such a tool could be misused. (An evil ISP doing a MITM with their own RPM Test server?) Thanks.

@richb-hanover
Copy link
Author

I'm going to close this in favor of #20

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

No branches or pull requests

4 participants