Golang issue x509: cannot verify signature: algorithm unimplemented on net/http - ssl

I was writing a very simple Golang script and use this library golang-jenkins to connect with our internal HTTPS server. But I face the following x509 cert issue and wasn't sure what to do with the x509 cert problem. Our team has zero access to Jenkins and would like to know what else we can do to dig more about the issue.
$ go run jenkins.go
2014/07/28 22:00:29 [] Get https://jenkins.mydomain.com/api/json: x509: certificate signed by unknown authority (possibly because of "x509: cannot verify signature: algorithm unimplemented" while trying to verify candidate authority certificate "MyDomain Internal Root CA")
using curl:
$ curl -v "https://jenkins.mydomain.com/api/json"
* Adding handle: conn: 0x7f8469004000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f8469004000) send_pipe: 1, recv_pipe: 0
* About to connect() to jenkins.mydomain.com port 443 (#0)
* Trying 10.38.8.70...
* Connected to jenkins.mydomain.com (10.38.8.70) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: jenkins.mydomain.com
* Server certificate: MyDomain Server CA - 2014
* Server certificate: MyDomain Internal Root CA
> GET /api/json HTTP/1.1
> User-Agent: curl/7.30.0
> Host: jenkins.mydomain.com
> Accept: */*
>
< HTTP/1.1 200 OK
* Server nginx is not blacklisted
< Server: nginx
< Date: Tue, 29 Jul 2014 05:03:45 GMT
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: JSESSIONID.214ca1a4=1ry000odf815goiv7vl8tr627;Path=/;Secure
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< X-Jenkins: 1.554.3
< X-Jenkins-Session: c660ff91

TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 is currently broken in Go, it will be supported in v1.4, the only workaround is to downgrade the TLS MaxVersion.
A quick look at golang-jenkins, it doesn't allow specifying the http.Client to use and just uses http.DefaultClient, the only ugly way to downgrade TLS's MaxVersion is to override http.DefaultClient.Transport.
You should be able to do something like this in func init() before you try to connect to anything:
cfg := &tls.Config{
MaxVersion: tls.VersionTLS11, // try tls.VersionTLS10 if this doesn't work
PreferServerCipherSuites: true,
}
http.DefaultClient.Transport = &http.Transport{
TLSClientConfig: cfg,
}
Keep in mind this will set the transport for anything that uses http.DefaultClient directly, like http.Get, however if you use your own instance, you will be fine.
Discussion about the bug: https://groups.google.com/forum/#!topic/golang-nuts/oK3EBAY2Uig

Related

Apache HTTP2 h2c mode not working properly

I would like to enable h2c mode on apache, so I can use HTTP2.0 protocol. In my virtual host configuration I have included the line:
Protocols h2c http/1.1
I have also followed the advise to disable prefork but it doesn't work as expected.
Currently I'm using apache 2.4.29 on Ubuntu.
Case 1) curl requesting http2 upgrade
$ curl -vs --http2 http://domain1.com
* Rebuilt URL to: http://domain1.com/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to domain1.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: domain1.com
> User-Agent: curl/7.58.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
>
< HTTP/1.1 101 Switching Protocols
< Upgrade: h2c
< Connection: Upgrade
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=28
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< date: Sun, 00 Jan 1900 00:00:00 GMT
< server: Apache/2.4.29 (Ubuntu)
< last-modified: Fri, 29 Mar 2019 13:52:29 GMT
< etag: W/"2aa6-5853bfb4c71ac"
< accept-ranges: bytes
< content-length: 10918
< vary: Accept-Encoding
< content-type: text/html
<
.... [snip website code] ....
Case 2) curl directly using http2
$ curl -vs --http2-prior-knowledge http://domain1.com
* Rebuilt URL to: http://domain1.com/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to domain1.com (127.0.0.1) port 80 (#0)
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5604f1cb1580)
> GET / HTTP/2
> Host: domain1.com
> User-Agent: curl/7.58.0
> Accept: */*
>
* http2 error: Remote peer returned unexpected data while we expected SETTINGS frame. Perhaps, peer does not support HTTP/2 properly.
As you can see Case 1 is working as expected, but Case 2 is not returning the site. Why is this happening? Is it because Apache is restricting direct use of HTTP2.0 without security?
Hope you can give me an answer as I don't know why things are not working now.
I think I have found the answer, and I think it is a bug in the lastest Apache versions. If I only enable h2c in a virtual host the error persist, but if I enable it on the default virtual host (000-default.conf) everything seems to be working fine.
Another potential solution I have tested and that is working is to enable the protocols h2 and h2c in every virtual host by modifying the mods-enabled/http2.load file:
LoadModule http2_module /usr/lib/apache2/modules/mod_http2.so
<IfModule http2_module>
Protocols h2 h2c http/1.1
</IfModule>
Any of the above mentioned options seems to make the system works as expected both with protocol negotiation and with prior knowledge.

Heroku Hobby Dyno: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR, server verification OK but ALPN server does not agree to protocol

I have a simple app where the client is sending a request to join a websocket channel upon page load via a wss connection. I have deployed my app to heroku at domain my_app.heroku.com. Whenever I open my site, I get the error Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR. I understand that this is an SSL issue, and also that to use Heroku's SSL, you must be on a hobbyist account. So, I upgraded the app to hobbyist (one day ago), but it has not fixed the problem.
I have googled the issue, and from what I see it appears that additional setup beyond upgrading to Heroku Hobby should only be required if using a custom domain-name, which I am not. How can I get the SSL working on my my_app.heroku.com domain with the Hobby dyno?
EDIT: If I run curl -vI <my_app>.heroku_app.com I get the following:
curl -vI https://<my_app>.herokuapp.com
* Rebuilt URL to: https://<my_app>.herokuapp.com/
* Trying __.___.___.___...
* Connected to <my_app>.herokuapp.com (__.___.___.___) port 443
(#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 592 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* common name: *.herokuapp.com (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject: C=US,ST=California,L=San Francisco,O=Heroku\, Inc.,CN=*.herokuapp.com
* start date: Wed, 19 Apr 2017 00:00:00 GMT
* expire date: Mon, 22 Jun 2020 12:00:00 GMT
* issuer: C=US,O=DigiCert Inc,OU=www.digicert.com,CN=DigiCert SHA2
High Assurance Server CA
* compression: NULL
* ALPN, server did not agree to a protocol
> HEAD / HTTP/1.1
> Host: <my_app>.herokuapp.com
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: Cowboy
Server: Cowboy
< Connection: keep-alive
Connection: keep-alive
< Content-Type: text/html; charset=utf-8
Content-Type: text/html; charset=utf-8
< Content-Length: 1154
Content-Length: 1154
< Date: Thu, 22 Nov 2018 08:39:51 GMT
Date: Thu, 22 Nov 2018 08:39:51 GMT
< Via: 1.1 vegur
Via: 1.1 vegur
I found the answer after finally finding this question. I thought all along the issue was due to setting up SSL certificates on Heroku, however it was due to my client side code. Per the tutorial I was following, the WS connection was "wss://my_app.herokuapp.com:80/subscribe". Removing the port number was the fix.

Proxy request through Apache host to docker container

I have an Ubuntu server host running an Apache web server. Running on this host is a docker container serving Geoserver (via Tomcat) (built from this image) with a port configuration as such: 0.0.0.0:32770->8080/tcp
I can access Geoserver just fine using http://my.domain:32770/geoserver
I have a redirect configured in Apache on the host to serve all requests over HTTPS (see code snippet below), which does not play nicely with the port in requests like this(ie. https://my.domain:32770/geoserver)
<VirtualHost *:80>
# sending http requests to https
ServerName data.nrri.umn.edu
Redirect permanent / https://data.nrri.umn.edu/
</VirtualHost>
My attempt at a workaround for this is to use the ProxyPass directive in an Apache config file:
ProxyRequests Off
ProxyPreserveHost On
ProxyPass /my-geoserver http://127.0.0.1:32770/geoserver
ProxyPassReverse /my-geoserver http://127.0.0.1:32770/geoserver
When I use the URL that I would expect would get me to the Geoserver home page like the one above does (ie. http://my.domain/my-geoserver) I am redirected to
https://my.domain/geoserver/index.html and presented with 404 Not Found.
I should also note that both http://my.domain:32770/geoserver and http://my.domain:32770/geoserver/index.html resolve to http://my.domain:32770/geoserver/web/
What am I doing wrong here?
Edit
Output from curl -L -v -o /dev/null data.nrri.umn.edu/nra-geoserver
* Hostname was NOT found in DNS cache
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 131.212.123.7...
* Connected to data.nrri.umn.edu (131.212.123.7) port 80 (#0)
> GET /nra-geoserver HTTP/1.1
> User-Agent: curl/7.35.0
> Host: data.nrri.umn.edu
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Fri, 19 May 2017 15:28:35 GMT
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Location: /geoserver/index.html
< Content-Length: 0
< Set-Cookie: JSESSIONID=DFECFFB91353A34C407488EAAF70A2B4; Path=/geoserver; HttpOnly
<
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
* Connection #0 to host data.nrri.umn.edu left intact
* Issue another request to this URL: 'HTTP://data.nrri.umn.edu/geoserver/index.html'
* Found bundle for host data.nrri.umn.edu: 0x95b8c0
* Re-using existing connection! (#0) with host data.nrri.umn.edu
* Connected to data.nrri.umn.edu (131.212.123.7) port 80 (#0)
> GET /geoserver/index.html HTTP/1.1
> User-Agent: curl/7.35.0
> Host: data.nrri.umn.edu
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Date: Fri, 19 May 2017 15:28:35 GMT
* Server Apache/2.4.7 (Ubuntu) is not blacklisted
< Server: Apache/2.4.7 (Ubuntu)
< Location: https://data.nrri.umn.edu/geoserver/index.html
< Content-Length: 336
< Content-Type: text/html; charset=iso-8859-1
<
* Ignoring the response-body
{ [data not shown]
100 336 100 336 0 0 38536 0 --:--:-- --:--:-- --:--:-- 38536
* Connection #0 to host data.nrri.umn.edu left intact
* Issue another request to this URL: 'https://data.nrri.umn.edu/geoserver/index.html'
* Found bundle for host data.nrri.umn.edu: 0x95b8c0
* Hostname was NOT found in DNS cache
* Trying 131.212.123.7...
* Connected to data.nrri.umn.edu (131.212.123.7) port 443 (#1)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
* SSLv3, TLS handshake, CERT (11):
{ [data not shown]
* SSLv3, TLS handshake, Server key exchange (12):
{ [data not shown]
* SSLv3, TLS handshake, Server finished (14):
{ [data not shown]
* SSLv3, TLS handshake, Client key exchange (16):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Finished (20):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
{ [data not shown]
* SSLv3, TLS handshake, Finished (20):
{ [data not shown]
* SSL connection using ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
* subject: C=US; ST=MN; L=Minneapolis; O=University of Minnesota; OU=Natural Resources Research Institute; CN=data.nrri.umn.edu
* start date: 2017-04-18 00:00:00 GMT
* expire date: 2020-04-17 23:59:59 GMT
* subjectAltName: data.nrri.umn.edu matched
* issuer: C=US; ST=MI; L=Ann Arbor; O=Internet2; OU=InCommon; CN=InCommon RSA Server CA
* SSL certificate verify ok.
> GET /geoserver/index.html HTTP/1.1
> User-Agent: curl/7.35.0
> Host: data.nrri.umn.edu
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Date: Fri, 19 May 2017 15:28:35 GMT
* Server Apache/2.4.7 (Ubuntu) is not blacklisted
< Server: Apache/2.4.7 (Ubuntu)
< Content-Length: 301
< Content-Type: text/html; charset=iso-8859-1
<
{ [data not shown]
100 301 100 301 0 0 4404 0 --:--:-- --:--:-- --:--:-- 4404
* Connection #1 to host data.nrri.umn.edu left intact
OK, so there are two redirects happening. I am not sure of a good way to solve the first one (and it is possible the solution solves it as well as the second one). But the second one, you should be able to add a trailing / to the paths. The resulting proxy directives would be:
ProxyPass /my-geoserver/ http://127.0.0.1:32770/geoserver/
ProxyPassReverse /my-geoserver/ http://127.0.0.1:32770/geoserver/
Give this a try first at http://data.nrri.umn.edu/geoserver/index.html and then with http://data.nrri.umn.edu/nra-geoserver and see where it fails next. If the former works but the latter fails, we'll probably need to edit some Tomcat configuration as well (to enable the remote IP valve https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html).

Heroku ssl certficate not switched with custom domain

I have a heroku app (whatever-app-11123) and I want to use a custom domain through ssl (https://myapp.co).
I have bought the certificate and followed all the instructions provided by heroku.
Strange thing is that https://whatever-app-11123 is displaying the myapp.co certificate and https://myapp.co is displaying the *.herokuapp.com certificate.
I need this to be the other way around : myapp.co with the myapp.co certificat.
Any hints on how achieving this?
Results of different commands :
herok:certs
Endpoint Common Name(s) Expires Trusted
--------------------------------- ---------------------------------------- -------------------- -------
whatever-app-11123.herokuapp.com myapp.co, www.myapp.co 2017-02-12 23:59 UTC True
curl -kvI https://www.myapp.co
* Adding handle: conn: 0x7fbd03804000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fbd03804000) send_pipe: 1, recv_pipe: 0
* About to connect() to www.myapp.co port 443 (#0)
* Trying 46.132.168.142...
* Connected to www.myapp.co (46.132.168.142) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: *.herokuapp.com
* Server certificate: DigiCert SHA2 High Assurance Server CA
* Server certificate: DigiCert High Assurance EV Root CA
> HEAD / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: www.myapp.co
> Accept: */*
>
< HTTP/1.1 302 Found
HTTP/1.1 302 Found
* Server Cowboy is not blacklisted
<
* Connection #0 to host www.myapp.co left intact
Here's the answer: check your DNS redirection. Make sure it is a CNAME type and MOST OF ALL (what I did wrong) the redirection should be :
www.myapp.co -> whatever-app-11123.herokuapp.com
myapp.co -> whatever-app-11123.herokuapp.com
and not
www.myapp.co -> myapp.co
myapp.co -> whatever-app-11123.herokuapp.com

X509 parsing error, 'negative serial number' while pulling repository

Our server access internet through a proxy. When I try to run a pull command such as
sudo docker run -t -i ubuntu:14.04 /bin/bash
I get the below error:
Get https://index.docker.io/v1/repositories/ubuntu/images: tls: failed to parse
certificate from server: x509: negative serial number
The wget command wget -S -d -O - https://get.docker.io yields the below output:
Setting --output-document (outputdocument) to - DEBUG output created
by Wget 1.13.4 on linux-gnu.
URI encoding = UTF-8' URI encoding =UTF-8'
--2014-08-27 17:13:46-- https://get.docker.io/ Connecting to :... connected. Created socket 3. Releasing
0x00000000016829f0 (new refcount 0). Deleting unused
0x00000000016829f0.
---request begin--- CONNECT get.docker.io:443 HTTP/1.1 User-Agent: Wget/1.13.4 (linux-gnu) Proxy-Authorization: Basic
Y3RzXDMxMzMwMDpzd2VldGZlbC4yOQ==
---request end--- proxy responded with: [HTTP/1.1 200 Connection established Date: Wed, 27 Aug 2014 11:49:52 GMT Age: 0 Via: 1.0
xaahshshhds
] Initiating SSL handshake. Handshake successful; connected socket 3
to SSL handle 0x00000000016831c0 certificate: subject:
/emailAddress=aaa#bbbb.com/C=yy/ST=aa/L=xx/O=yy/OU=mycompany/CN=get.docker.io
issuer:
/emailAddress=aaa#bbbb.com/C=yy/ST=aa/L=xx/O=yy/OU=mycompany/CN=mycompany
ERROR: cannot verify get.docker.io's certificate, issued by
/emailAddress=aaa#bbbb.com/C=yy/ST=aa/L=xx/O=yy/OU=mycompany/CN=mycompany':
Unable to locally verify the issuer's authority. To connect to
get.docker.io insecurely, use--no-check-certificate'. Closed 3/SSL
0x00000000016831c0
Please give me some directions on how I should go about this issue.
EDIT:
I ve now disabled the proxy for this IP segment but I still get the same error.
The command: wget -S -d -O - https://get.docker.io gets the below output now:
Setting --output-document (outputdocument) to -
DEBUG output created by Wget 1.13.4 on linux-gnu.
URI encoding = `UTF-8'
--2014-09-04 11:26:12-- https://get.docker.io/
Resolving get.docker.io (get.docker.io)... 162.242.195.77
Caching get.docker.io => 162.242.195.77
Connecting to get.docker.io (get.docker.io)|162.242.195.77|:443... connected.
Created socket 3.
Releasing 0x00000000022d8fd0 (new refcount 1).
Initiating SSL handshake.
Handshake successful; connected socket 3 to SSL handle 0x00000000022dabd0
certificate:
subject: /serialNumber=exkd9EjUozUulWIyUDurQPMEPBLSc2Bq/OU=GT98568428/OU=See www.rapidssl.com/resources/cps (c)13/OU=Domain Control Validated - RapidSSL(R)/CN=*.docker.io
issuer: /C=US/O=GeoTrust, Inc./CN=RapidSSL CA
X509 certificate successfully verified and matches host get.docker.io
---request begin---
GET / HTTP/1.1
User-Agent: Wget/1.13.4 (linux-gnu)
Accept: */*
Host: get.docker.io
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 503 Service Unavailable
Server: nginx/1.7.1
Date: Thu, 04 Sep 2014 06:03:28 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache
---response end---
HTTP/1.1 503 Service Unavailable
Server: nginx/1.7.1
Date: Thu, 04 Sep 2014 06:03:28 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache
Registered socket 3 for persistent reuse.
Skipping 108 bytes of body: [<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
] done.
2014-09-04 11:26:13 ERROR 503: Service Unavailable.
subject: /emailAddress=aaa#bbbb.com/C=yy/ST=aa/L=xx/O=yy/OU=mycompany/CN=get.docker.io
issuer: /emailAddress=aaa#bbbb.com/C=yy/ST=aa/L=xx/O=yy/OU=mycompany/CN=mycompany
It looks like the proxy in your company uses SSL interception to inspect SSL traffic, which means that you get a certificate signed by the proxy CA of your company instead of the original certificate. It also looks like that this proxy CA is not trusted by your system and thus the verification fails.
I would recommend that you contact your firewall administrator on how to deal with the problem. Either they will add an exception for the SSL inspection, or they will tell you which certificate you need to import as trusted in your system.
This should be fixed for any Docker compiled with Go 1.6+, see: https://github.com/golang/go/commit/a0ea93dea5f5741addc8c96b7ed037d0e359e33f.