start-iap-tunnel unable to connect to a listening port - ssl

I'm installing OpenVPN Access Server on a Google Cloud instance. Its webUI listens on port 943 using https. It has a self-signed certificate whose name doesn't match the server's hostname (10.150.0.2). I can't start an SSH tunnel. I'm looking for a way to troubleshoot the connection from the IAP service to my server.
The command I'm running is gcloud compute start-iap-tunnel vpn 943 --local-host-port=localhost:943 I receive the normal Testing if tunnel connection works message.
It errs out with ERROR: (gcloud.compute.start-iap-tunnel) While checking if a connection can be made: Error while connecting [4003: 'failed to connect to backend']. (Failed to connect to port 943)
If I add --log-http to the command invocation the relevant information follows (it looks like a normal req/resp cycle with a 200 that I assume is from my client to the IAP service):
Testing if tunnel connection works.
=======================
==== request start ====
uri: https://oauth2.googleapis.com/token
method: POST
== headers start ==
b'content-type': b'application/x-www-form-urlencoded'
b'user-agent': b'google-cloud-sdk gcloud/367.0.0 command/gcloud.compute.start-iap-tunnel invocation-id/db27de82264f47fcb63f6680afaa8327 environment/None environment-version/None interactive/False from-script/False python/3.7.9 term/xterm-256color (Macintosh; Intel Mac OS X 21.2.0)'
== headers end ==
== body start ==
Body redacted: Contains oauth token. Set log_http_redact_token property to false to print the body of this request.
== body end ==
==== request end ====
---- response start ----
status: 200
-- headers start --
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Date: Fri, 24 Dec 2021 02:11:52 GMT
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Pragma: no-cache
Server: scaffolding on HTTPServer2
Transfer-Encoding: chunked
Vary: Origin, X-Origin, Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 0
-- headers end --
-- body start --
Body redacted: Contains oauth token. Set log_http_redact_token property to false to print the body of this response.
-- body end --
total round trip time (request+response): 0.246 secs
---- response end ----
----------------------
ERROR: (gcloud.compute.start-iap-tunnel) While checking if a connection can be made: Error while connecting [4003: 'failed to connect to backend']. (Failed to connect to port 943)
To my knowledge this is the limit of easily accessible troubleshooting for start-tap-tunnel.
Moving on to the local machine we can connect to 10.150.0.2:943 before puking a la certificate.
root#viongier:/usr/local/openvpn_as# wget https://10.150.0.2:943
--2021-12-24 02:01:47-- https://10.150.0.2:943/
Connecting to 10.150.0.2:943... connected.
ERROR: The certificate of ‘10.150.0.2’ is not trusted.
ERROR: The certificate of ‘10.150.0.2’ doesn't have a known issuer.
The certificate's owner does not match hostname ‘10.150.0.2’
It seems to me that my client happily connects to the IAP service which fails to connect to my server. I would expect to see an IAP error if it was erring out because of the cert. The only thing I can think of to test this is by generating a certificate whose issuer google likes. (LetsEncrypt for example.)

This message means that the backend does not have a socket open in the listening state. Common reasons are that no service has been started or a firewall is blocking the port.
To allow the Identity Aware Proxy into your VPC, allow traffic from 35.235.240.0/20.
ERROR: (gcloud.compute.start-iap-tunnel) While checking if a
connection can be made: Error while connecting [4003: 'failed to
connect to backend']. (Failed to connect to port 943)
This error means that the certificate provided does not match the address that the connection is made to:
ERROR: The certificate of ‘10.150.0.2’ is not trusted. ERROR: The
certificate of ‘10.150.0.2’ doesn't have a known issuer. The
certificate's owner does not match hostname ‘10.150.0.2’
Some clients, such as wget support ignoring SSL certificate validation. For wget see the --no-check-certificate flag.
Once you solve that problem you will run into another set of problems:
Under normal circumstances, you can not use HTTPS with tunnels. Tunnels are a form of man in the middle. There are tricks that can be employed, none of them secure.
Commercial SSL certificates do not support IP addresses only public domain names. You would need to create your own self-signed certificate, which would not be trusted or do not validate the certificate.
The last issue is that HTTPS endpoints require encryption negotiation from the client party. The start-iap-tunnel command does not initiate encryption (TLS negotiation). This command also does not do any form of certificate exchange and that is why you do not see an IAP error about certificates. This command only transfers data between the tunnel endpoints.
In summary, you cannot use HTTPS with TCP / SSH tunnels without deploying tricks and/or disabling features which defeats the purpose of HTTPS.

Allow IAP traffic through the firewall allowed my external client to connect to the internal port 943 via an IAP tunnel.
Allowing port 943 from 35.235.240.0/20 solved my problem.
More information is available at the GCP IAP docs

Related

kubectl exec "error: unable to upgrade connection: Unauthorized"

I was using our Kubernetes cluster, I don't think so i have changed recently after deployment but am encountering this error
Error kubectl log with verbose :
01:49:42.691510 30028 round_trippers.go:444] Response Headers:
I0514 01:49:42.691526 30028 round_trippers.go:447] Content-Length: 12
10514 01:49:42.691537 30028 round_trippers.go:447] Content-Type: text/plain; charset=utf-8
I0514 01:49:42.691545 30028 round_trippers.go:447] Date: Tue, 14 May 2019 08:49:42 GMT
F0514 01:49:42.691976 30028 helpers.go:119] error: unable to upgrade connection:
Unauthorized
Kubelet running with below options :
/usr/local/bin/kubelet --logtostderr=true --v=2 --address=0.0.0.0 --node-ip=1******
--hostname-override=***** --allow-privileged=true --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --authentication-token-webhook --enforce-node-allocatable= --client-ca-file=/etc/kubernetes/ssl/ca.crt --pod-manifest-path=/etc/kubernetes/manifests --pod-infra-container-image=gcr.io/google_containers/pause-amd64:3.1 --node-status-update-frequency=10s --cgroup-driver=cgroupfs --max-pods=110 --anonymous-auth=false --read-only-port=0 --fail-swap-on=True --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice --cluster-dns=10.233.0.3 --cluster-domain=cluster.local --resolv-conf=/etc/resolv.conf --kube-reserved cpu=200m,memory=512M --node-labels=node-role.kubernetes.io/master=,node-role.kubernetes.io/node= --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin
API running with below options :
kube-apiserver --allow-privileged=true --apiserver-count=2 --authorization-mode=Node,RBAC --bind-address=0.0.0.0 --endpoint-reconciler-type=lease --insecure-port=0 --kubelet-preferred-address-types=InternalDNS,InternalIP,Hostname,ExternalDNS,ExternalIP --runtime-config=admissionregistration.k8s.io/v1alpha1 --service-node-port-range=30000-32767 --storage-backend=etcd3 --advertise-address=******* --client-ca-file=/etc/kubernetes/ssl/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/ssl/etcd/ca.pem --etcd-certfile=/etc/kubernetes/ssl/etcd/node-bg-kub-dev-1.pem --etcd-keyfile=/etc/kubernetes/ssl/etcd/node-bg-kub-dev-1-key.pem --etcd-servers=https://*******:2379,https://********:2379,https://*****:2379 --kubelet-client-certificate=/etc/kubernetes/ssl/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/ssl/apiserver-kubelet-client.key --proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-key-file=/etc/kubernetes/ssl/sa.pub --service-cluster-ip-range=10.233.0.0/18 --tls-cert-file=/etc/kubernetes/ssl/apiserver.crt --tls-private-key-file=/etc/kubernetes/ssl/apiserver.key
I think you messed your cert files or you played with RBAC profiles.
You can have a look at great guide by Kelsey Hightower called kubernetes-the-hard-way.
It's showing how to setup a whole cluster from beggining without any automation tools like kubeadm.
In part 04-certificate-authority - Provisioning a CA and Generating TLS Certificates.
You have exampled of certs being used in Kubernetes.
The Kubelet Client Certificates
Kubernetes uses a special-purpose authorization mode called Node Authorizer, that specifically authorizes API requests made by Kubelets. In order to be authorized by the Node Authorizer, Kubelets must use a credential that identifies them as being in the system:nodes group, with a username of system:node:<nodeName>. In this section you will create a certificate for each Kubernetes worker node that meets the Node Authorizer requirements.
Once certs are generated for workers and uploaded you need to generate kubeconfig for each worker.
The kubelet Kubernetes Configuration File
When generating kubeconfig files for Kubelets the client certificate matching the Kubelet's node name must be used. This will ensure Kubelets are properly authorized by the Kubernetes Node Authorizer.
Also this case might be helpful "kubectl exec" results in "error: unable to upgrade connection: Unauthorized"
I got fixed this issue.
Actually "/etc/kubernetes/ssl/ca.crt" in my both masters are same but in worker nodes "/etc/kubernetes/ssl/ca.crt" is totally different. So i just copied "/etc/kubernetes/ssl/ca.crt" from master to my worker nodes and restarted kubelet in workers nodes which fixed my issue.
But am not sure I did right changes for fix
I hope --client-ca-file=/etc/kubernetes/ssl/ca.crt should be same for all kubelet which is running master and workers

SSL connection fails to Datapusher app through port 8800, with NGINX reverse proxy to Apache

I am installing the datapusher service for CKAN.
CKAN has been configured to use an NGINX reverse proxy that routes client requests, following instructions here. SSL certificate is installed and configured in NGINX.
When trying to use the datapusher app to upload a file, it fails and Apache log gives this error:
Mon Apr 03 13:49:10.979179 2017] [:error] [pid 15468] 2017-04-03 13:49:10,979 CRITI [ckanext.datapusher.plugin] {'status_code': 403, 'message': 'An Error occurred while sending the job: 403 Client Error: Forbidden', 'details': u'<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\\n<html><head>\\n<title>403 Forbidden</title>\\n</head><body>\\n<h1>Forbidden</h1>\\n<p>You don\\'t have permission to access /job\\non this server.</p>\\n<hr>\\n<address>Apache/2.4.7 (Ubuntu) Server at 127.0.0.1 Port 8800</address>\\n</body></html>\\n'}
When testing access to the datapusher's 8800 port through openssl this is the output:
[Mon Apr 03 13:49:10.981049 2017] [:error] [pid 15468] [remote 127.0.0.1:6855] Error - <type 'exceptions.TypeError'>: notify() takes exactly 3 arguments (2 given)
open:/etc/ckan> openssl s_client -connect 127.0.0.1:8800
CONNECTED(00000003)
140385459791520:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:794:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 275 bytes
The datapusher docs give a workaround for bypassing SSL here, using the SSL_Verify config. I tried this and there was no change.
I think that I need to either:
1. Force the nginx reverse proxy to allow SSL connections through port 8800 (in addition to 443). Or...
2. Configure ckan/datapusher/apache/nginx to bypass SSL/https on port 880.
Any suggestions?
I believe the 403 error is at the point that CKAN sends a request to DataPusher to ask it to load a particular resource. DataPusher is running on Apache only and thus is on HTTP (not HTTPS) so there should be no issue with SSL. Check your CKAN config is the default:
ckan.datapusher.url = http://127.0.0.1:8800/
DataPusher's SSL_VERIFY setting is for a later request - when datapusher makes a request to CKAN at ckan.site_url, which for you will go via nginx over HTTPS. You may need this setting, depending on whether the SSL in your python is compatible. Reading the code it suggests you need quotes and make sure the key is all caps. i.e. in your datapusher_settings.py:
SSL_VERIFY = 'False'

Heroku SSL host not working (Heroku | No such app)

I successfully used Letsencrypt to generate certificates and I uploaded them to Heroku using:
this-site ********$ heroku addons:create ssl:endpoint
Creating ssl-graceful-41756... done, ($20.00/month)
Adding ssl-graceful-41756 to this-site... done
Next add your certificate with `heroku certs:add CERT KEY`.
Use `heroku addons:docs ssl` to view documentation.
this-site ********$ sudo heroku certs:add /etc/letsencrypt/live/www.this-site.com/fullchain.pem /etc/letsencrypt/live/www.this-site.com/privkey.pem
Resolving trust chain... done
Adding SSL Endpoint to this-site... done
this-site now served by qwasf-34234.herokussl.com
Certificate details:
Common Name(s): www.this-site.com
Expires At: 2016-09-02 19:15 UTC
Issuer: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
Starts At: 2016-06-04 19:15 UTC
Subject: /CN=www.this-site.com
SSL certificate is verified by a root authority.
However, when I visit qwasf-34234.herokussl.com, it is not working. It has a page that says: Heroku | No such app ; There is no app configured at that hostname.
Perhaps the app owner has renamed it, or you mistyped the URL.
I am copy and pasting the exact new host that heroku gave me. Going to https://qwasf-34234.herokussl.com yields the same page.
I verified the certificate with:
this-site ********$ heroku certs
Endpoint Common Name(s) Expires Trusted
-------------------------- --------------------- -------------------- -------
qwasf-34234.herokussl.com www.this-site.com 2016-09-02 19:15 UTC True
More checks:
this-site *******$ curl -kvI https://www.this-site.com
* Rebuilt URL to: https://www.michaelsutyak.com/
* Trying 23.21.142.230...
* Connected to www.this-site.com (23.21.142.230) port 443 (#0)
* TLS 1.2 connection using TLS_********************
* Server certificate: *.herokuapp.com
* Server certificate: DigiCert ******
* Server certificate: DigiCert *******
> HEAD / HTTP/1.1
> Host: www.this-site.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: Cowboy
Server: Cowboy
< Connection: keep-alive
Connection: keep-alive
< Vary: Accept-Encoding
Vary: Accept-Encoding
< Content-Type: text/html; charset=utf-8
Content-Type: text/html; charset=utf-8
< Date: Sat, 04 Jun 2016 20:57:00 GMT
Date: Sat, 04 Jun 2016 20:57:00 GMT
< Via: 1.1 vegur
Via: 1.1 vegur
<
* Connection #0 to host www.this-site.com left intact
What is going on here and how can this work? I just want https for my site.
You cannot access the Heroku SSL endpoint directly. That endpoint represents the hostname where you need to point your domain to, as explained in the DNS and domain configuration of the Heroku article.
If you want to point a subdomain (e.g. www.this-site.com), then create a DNS record CNAME in your DNS hosting provider that points the www record to the Heroku SSL endpoint:
www CNAME qwasf-34234.herokussl.com
If you want to point the root domain (this-site.com), then you need to use a provide that supports the CNAME-like record for the root domain, as explained in this Heroku article as you can't use a CNAME for the root domain.
Make sure your domain is not still pointing to the herokuapp.com hostname.
You can test my assertion by sending a cURL request to the SSL endpoint, but passing the Host header (as the browser would do).
$ curl -i qwasf-34234.herokussl.com -H "Host: www.this-site.com"
You cannot visit the qwasf-34234.herokussl.com domain that Heroku gives you. Instead, you are supposed to change your DNS to point to that as a CNAME, instead of qwasf-34234.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.

Why does a browser in a different domain not respond at all to "WWW Authenticate : Negotiate" header sent by mod_auth_kerb?

I have implemented SSO through mod_auth_kerb in our apache-active directory environment and it works just as expected. However the following knowledge is bugging me :
I requested a Kerberos protected page from two client machines, one user belonged to the Kerberos-setup domain and the other user belonged to some other domain.
I then compared the HTTP packets on the two machines. On both the machines, after the request for the Kerberos protected page is sent, the server responds with the following HTTP packet :
HTTP/1.1 401 Authorization Required
Date: Wed, 05 Sep 2012 14:25:20 GMT
Server: Apache WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="Kerberos Login"
Content-Length: 60
Connection: close
Content-Type: text/html; charset=iso-8859-1
However, after the above response from the server the client machine's browser belonging to the Kerberos-setup domain responds with a WWW-Authenticate : Negotiate 'token', whereas the other client browser(user belonging to some other domain) does not respond at all.
Now my understanding is, that the client belonging to the other domain should have also responded with its own TGT+Session key token, which the active directory should have rejected. But why this client does not respond at all to the server's WWW-Authenticate : Negotiate challenge is beyond my logic.
What is even more confusing is that the server's HTTP response(given above), does not contain any information about the domain it is linked to.
So on what basis is the client browser belonging to the correct domain decide that it has to respond to the server's WWW-Authenticate : Negotiate challenge, and on what basis does the client belonging to some other domain decide not to respond to the same ?
Note : Both the client machines have Windows 7 and active directory is a Windows 2008 server.
I am trying to understand mod_auth_kerb's implementation of SSO, and this particular knowledge is key to that.
The module has the option KrbMethodK5Passwd turned on. It sends a Basic header to collect you Kerberos credentials. This is pointless for a non-domain client. Disable this option.
There is a hierarchy of strengths of auth mechanisms, the browser is obliged to choose the best. This is: Negotiate, Digest, NTLM, Basic.