"handshake failed" error when using openresty (resty.http) - ssl

I am trying to make a call to a HTTPS upstream server in lua code in openresty. Code is as below:
local http = require "resty.http"
local M = {}
function M.makeHttpCall()
local httpc = http.new()
local res, err = httpc:request_uri("https://<url>", {
method = "GET",
ssl_verify = false
})
if not res then
ngx.status = 500
ngx.say("Error: ", err)
return
end
.....
end
nginx.conf has the following relevant configuration:
server {
listen 8080;
resolver local=on ipv6=off;
.....
location /httpcall {
default_type 'application/json';
content_by_lua_block {
require("../lua-modules/http")["makeHttpCall"]()
}
}
Following error is logged in error.log:
SSL_do_handshake() failed (SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:SSL alert number 40), client: 127.0.0.1, server: , request: "GET /httpcall HTTP/1.1", host: "localhost:8080"
http.lua:15: makeHttpCall(): **request failed: handshake failed**, client: 127.0.0.1, server: , request: "GET /httpcall HTTP/1.1", host: "localhost:8080"
HTTP endpoint can be called successfully.
Any pointers to resolve the issue please?
Thanks!

Related

nuxt-mail fails with a 504 with nginx reverse proxy

I configured nuxt-mail to send emails from our nuxt app.
The baseURL of my app is changed to "https://localhost:3000/app" instead of "https://localhost:3000"
So, nginx redirects all calls to '/' to a static app. And all calls to '/app' to a dynamic app.
The issue is that on production, nuxt-mail is unable to send email through a post to '/app/mail/send'.
I tried with setting axios baseURL on nuxt.config.js as suggested on the nuxt-mail npm/github page
I don't see a path to send or mail in .nuxt/router.js
file: contact.vue
Note: WEBSITE_DOMAIN points to https://localhost:3000 locally and valid web domain on production in this format: https://www.production_website.com
<script>
...
methods: {
...
sendMail(){
this.$axios.post(
this.$config.WEBSITE_DOMAIN+'/app/mail/send',
{
...
}
...
}
...
</script>
file: nuxt.config.js
...
export default{
...
router: {
base: '/app/'
},
...
}
Note: I did configure the upstream logs from nginx to app server
Access log from nginx on production
49.205.150.249 - - [04/May/2022:15:30:54 +0000] "POST /app/mail/send HTTP/1.1" 504 167 "https://www.<xxxxxxxxx_NAME>.com/app/contact"
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:99.0) Gecko/20100101
Firefox/99.0"
Error log from nginx on production
2022/05/04 15:30:54 [error] 2106#2106: *38 upstream timed out (110:
Connection timed out) while reading response header from upstream,
client: 49.205.150.249, server: <xxxxxxxxx_NAME>.com, request: "POST
/app/mail/send HTTP/1.1", upstream:
"https://<xxxxxxxxx_IP>:3000/app/mail/send", host:
"www.<xxxxxxxxx_NAME>.com", referrer:
"https://www.<xxxxxxxxx_NAME>.com/app/contact"
What am I missing here? It works perfectly on my staging though.
The port allowing SMTP on the production instance was not open. On AWS EC2, I needed to enable outbound rules on the corresponding security group.

How can I upload via curl to an S3 presigned url using the v3 api?

I'm trying to use the v3 api to create a pre signed url for uploading. I am able to use this config to access other parts of the api just fine.
I'm running minio in a docker container and my code is running in another container.
Below is how I'm generating a presigned url:
import { PutObjectCommand, S3, S3Client } from "#aws-sdk/client-s3"
import { getSignedUrl } from "#aws-sdk/s3-request-presigner"
const config = {
endpoint: "http://minio:9000",
forcePathStyle: true,
region: 'us-east-1',
credentials: {
accessKeyId: '...',
secretAccessKey: '...',
}
}
const client = new S3Client(config)
const command = new PutObjectCommand({
Bucket: 'uploads',
Key: 'test123',
});
const url = await getSignedUrl(this.client, command, { expiresIn: 3600 });
And then that produces a url such as:
http://minio:9000/uploads/test123?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AjAOk2gNRU%2F20210727%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210727T182833Z&X-Amz-Expires=3600&X-Amz-Signature=3e7407384dd87e2715d3daa2c58e53e1bfb619ec0b495009558fbe3094add5ef&X-Amz-SignedHeaders=host&x-id=PutObject
I swap minio:9000 to localhost but set the Host to minio then make the request via curl like so:
curl -H "Host: minio:9000" -X PUT "$URL" --upload-file ~/Desktop/hello.txt -v
Its giving me this error:
The request signature we calculated does not match the signature you provided. Check your key and signing method.
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 9000 (#0)
> PUT /uploads/test123?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AjAOk2gNRU%2F20210727%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210727T184545Z&X-Amz-Expires=3600&X-Amz-Signature=44058eebea8e31afb60a5993f9d26b644c40bebda24004b63225a51d227e7723&X-Amz-SignedHeaders=host&x-id=PutObject HTTP/1.1
> Host: minio:9000
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 252
> Expect: 100-continue
>
< HTTP/1.1 403 Forbidden
< Accept-Ranges: bytes
< Content-Length: 399
< Content-Security-Policy: block-all-mixed-content
< Content-Type: application/xml
< Server: MinIO
< Vary: Origin
< X-Amz-Request-Id: 1695BA2F941F436A
< X-Xss-Protection: 1; mode=block
< Date: Tue, 27 Jul 2021 18:45:53 GMT
< Connection: close
<
<?xml version="1.0" encoding="UTF-8"?>
* Closing connection 0
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><Key>test123</Key><BucketName>uploads</BucketName><Resource>/uploads/test123</Resource><RequestId>1695BA2F941F436A</RequestId><HostId>fb52d19a-7b70-4620-9a52-726ba6fd9df5</HostId></Error>
I've tried sending more or less headers via curl it seems to have no effect. I dont' know why it thinks the signatures don't match either.
the signature is generated using the parameters this.client, command, { expiresIn: 3600 }, this.client includes S3Client(config), config includes endpoint: "http://minio:9000" and you are modifying the endpoint after the signature is generated thereby invalidating the signature, as the error suggests.

Error in Postman: Error: write EPROTO 8768:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:

During request GET in Postman (https://localhost:9001/test)
I've received an error:
Error: write EPROTO 8768:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:c:\users\administrator\buildkite-agent\builds\pm-electron\postman\electron-release\vendor\node\deps\openssl\openssl\ssl\record\ssl3_record.c:252:
Warning: This request did not get sent completely and might not have all the required system headers.
Postman Configuration:
SSL certificate verification is disabled;
Proxy configuration - Default Proxy Configuration and Proxy configurations for sending requests are disabled;
Request timeout in ms - 0.
For Localhost we don't really need https, please try with http://localhost:9001/test
check that you are using the HTTP protocol not HTTPS to send requests to the server:
example
export const config = {
baseUrl: "http://localhost:4000"
}
it has to be the http not https for localhost
"http://localhost:3000"
NOT
"https://localhost:3000"
const transporter = nodemailer.createTransport({
host:'smtp.gmail.com',
port:587,
secure:false,
requireTLC:true,
auth: {
user:'youmail#gmail.com',
pass:'youpass'
}
}
Notice that secure: is false.
The error occurs when secure: is true.
the reason was in an incorrect link.
In the controller I have used
#RequestMapping(value="/{baseSiteId}/test")
And this {baseSiteId} was not what I expected.

Timeout error while connecting to SQL Server: Connection Error: Failed to connect to servername\instancename in 15000ms

The error code is code ETIMEOUT. I am using SQL Server 2014, NodeJs version v12.16.2 and I am running this code in Visual Studio Code.
I have created the database and the table is also created with some records. For the server name, I have also tried giving the FQDN, but it didn't work.
This is the code snippet:
const express = require('express');
const app = express();
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
app.get('/', function(req, res) {
res.send('<hHii</h');
});
const sql = require('mssql');
var config = {
user: 'domain\username',
password: 'mypwd',
server: 'servername',
host: 'hostname',
port: '1433',
driver: 'tedious',
database: 'DBname',
options: {
instanceName: 'instancename'
}
};
sql.connect(config, function(err) {
if (err)
console.log(err);
let sqlRequest = new sql.Request();
//var sqlRequest = new sql.Request(connection)
let sqlQuery = 'SELECT * from TestTable';
sqlRequest.query(sqlQuery, function(err, data) {
if (err) console.log(err);
console.log(data);
//console.table(data.recordset);
// console.log(data.rowAffected);
//console.log(data.recordset[0]);
sql.close()
});
});
const webserver = app.listen(5000, function() {
console.log('server is up and running....');
});
Error:
tedious deprecated The default value for `config.options.enableArithAbort` will change from `false` to `true` in the next major version of `tedious`. Set the value to `true` or`false` explicitly to silence this message.
node_modules\mssql\lib\tedious\connection-pool.js:61:23
server is up and running....
ConnectionError: Failed to connect to servername\instantname in 15000ms
at Connection.<anonymous(..\SQL\Sample\sample\node_modules\mssql\lib\tedious\connection-pool.js:68:17)
at Object.onceWrapper (events.js:417:26)
at Connection.emit (events.js:310:20)
at Connection.connectTimeout (..\SQL\Sample\sample\node_modules\tedious\lib\connection.js:1195:10)
at Timeout._onTimeout (..\SQL\Sample\sample\node_modules\tedious\lib\connection.js:1157:12)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7) {
code: 'ETIMEOUT',
originalError: ConnectionError: Failed to connect to INPUNPSURWADE\DA in 15000ms
at ConnectionError (..\SQL\Sample\sample\node_modules\tedious\lib\errors.js:13:12)
at Connection.connectTimeout (..\SQL\Sample\sample\node_modules\tedious\lib\connection.js:1195:54)
at Timeout._onTimeout (..\SQL\Sample\sample\node_modules\tedious\lib\connection.js:1157:12)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7) {
message: 'Failed to connect to servername\instantname in 15000ms',
code: 'ETIMEOUT'
},
name: 'ConnectionError'
}
ConnectionError: Connection is closed.
at Request._query (..\SQL\Sample\sample\node_modules\mssql\lib\base\request.js:462:37)
at Request._query (..\SQL\Sample\sample\node_modules\mssql\lib\tedious\request.js:346:11)
at Request.query (..\SQL\Sample\sample\node_modules\mssql\lib\base\request.js:398:12)
at Immediate.<anonymous(..\SQL\Sample\sample\index.js:43:12)
at processImmediate (internal/timers.js:458:21) {
code: 'ECONNCLOSED',
name: 'ConnectionError'
}
Go to Start menu in Windows, search for "Services" and open it.
Look for "SQL Server Browser"
Right click on it and go to Properties.
Switch "Start up type" to "Automatic"
Click Ok
Right click on it again and Start the service.
It should work after that!
You might make a typo in host/port, or the server doesn't listen external interfaces (it might be configured to liten 127.0.0.1 only)
to check that the server is listening to incoming connections, run in terminal the following:
telnet <hostname> <port>
(mac/linux only)
If it says "Unable to connect to remote host: Connection refused" it means the host is there but it doesn't listen the port.
If it says "Unable to connect to remote host: Connection timed out" then the host might not be there, ot doesn't listen to the port.
You may also want to check if your firewall allows connection to that server.

How can I fix a TLS handshake error using Go on Heroku?

I have a simple proxy that listens to HTTP and HTTPS connections on the same port.
However I'm seeing weird TLS handshake errors that seem to be caused by the Heroku router:
heroku[router]: sock=backend at=error code=H18 desc="Server Request Interrupted" method=GET path="/favicon.ico" host=banana.camp request_id=f56144c8-e480-476a-90b8-429b490f1ff5 fwd="24.67.185.77" dyno=web.1 connect=0ms service=1ms status=503 bytes=7 protocol=https
http: TLS handshake error from 10.81.159.108:19578: tls: first record does not look like a TLS handshake
http: TLS handshake error from 172.17.117.25:36924: EOF
Is there any way to fix or ignore them? Any clues are greatly appreciated.
Thanks!
func InitServer() error {
m := autocert.Manager{
Cache: autocert.DirCache(*StorageDir),
Prompt: autocert.AcceptTOS,
HostPolicy: func(ctx context.Context, host string) error {
return nil
},
}
errchan := make(chan error)
s := &http.Server{
Addr: ":" + os.Getenv("PORT"),
TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
Handler: ServeHTTP(),
}
go (func() {
errchan <- http.ListenAndServe(":"+os.Getenv("PORT"), m.HTTPHandler(nil))
})()
errchan <- s.ListenAndServeTLS("", "")
return <-errchan
}
func ServeHTTP() http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if upstreams, ok := Hosts[req.Host]; ok {
forwarder, _ := forward.New(forward.PassHostHeader(true))
loadbalancer, _ := roundrobin.New(forwarder)
for _, upstream := range upstreams {
if url, err := url.Parse(upstream); err == nil {
loadbalancer.UpsertServer(url)
} else {
log.Fatal("InitHostsList: ", err)
}
}
loadbalancer.ServeHTTP(res, req)
return
}
http.Error(res, "The request service couldn't be found here", http.StatusNotImplemented)
})
}
TLS termination is handled by the Heroku router and can't be done at the app level ¯_(ツ)_/¯
You can't listen to both http and https on the same port, and those log-errors are cases when you have http clients try to connect to the app.
By default, the golang http server only supports listening to http or https traffic on a given port (not both). To listen to https traffic, you need to use http.ListenAndServeTLS.
If you are directing both http and https traffic at at point configured for only one, you will end up seeing errors.
There are third-party solution (like cmux) that support hosting both secure and insecure traffic on the same port. Not as easy as separating the ports, but if it's something you want to do, they have an example configuration in the README.