How to connect to FTP server with TLS authentication in Rails Application? - ruby-on-rails

I have setup FTP server and enabled TLS/SSL to the server following this tutorial. Once the setup was done, I tried to connect to it from FileZilla and it worked. Now I want to do the same with my rails application.
I came across similar questions and there were some solutions. But all the solutions suggested ignoring the verification as:
OpenSSL::SSL::VERIFY_NONE
But this beats the purpose of having FTP server with TLS enabled.
I came across an article that suggested setting ssl: true like:
ftps = Net::FTP.new(
host,
ssl: true,
username: username,
password: password
)
However, this did not work. I get
SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate)
I found some references about the parameters but am confused about how to use them.

You have a server with a self signed certificate, SSL will fail to verify that always. Right now you have three ways to solve that:
Change your code so it accepts self signed certificates (you already stated this won't work for you).
Request a valid certificate (Letsencrypt seems like a good option).
Use mkcert to create "valid" certificates for development.
If your FTP server is a public server, you should go with #2. #3 is a big help if you're just doing some experiments or setting a local development server.

Related

Ruby RestClient SSL cannot verify

I was using app on two domains:
domain.com,
differentdomain.com
All calls from the app by RestClient was done on differentdomain.com. Right now i'm switching calls to domain.com because there is no need to have two different domains.
So i created subdomain different.domain.com. I have valid SSL certificate (with wildcard), properly set with nginx server.
When i enter different.domain.com in my browser i get page with valid ssl certificate. It's working ok without any bugs.
The problem is when i'm trying to call subdomain via RestClient. I'm getting this error:
RestClient::SSLCertificateNotVerified (SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
Do i need update cert/key somewhere else ?
Normally this SSL error indicates some issues in the certification installation such as missing intermediate certificate. You could verify your ssl certificate from https://www.ssllabs.com/ssltest/analyze.html
If you saw "Chain Issue: Incomplete", most likely you will need to re-install your intermediate certificate again (https://community.qualys.com/thread/11685)
give it a try.

Heroku Rails Net::HTTP: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

I have a Rails app running on a Heroku server and I'm having trouble communicating with an external server using Net::HTTP over HTTPS. The error I'm receiving whenever I attempt to POST to an external proprietary API over HTTPS is:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
I've done quite a few hours of Googling around for an answer to the issue I'm encountering, but to no avail. Here's my environment:
Heroku Dyno running Cedar 14 (was running Cedar 10, upgraded to Cedar 14 to see if it would affect the issue - no joy)
Rails 3.2.14rc2
Ruby 2.1.2
"Fixes" I have tried:
Running the certified gem (which has actually seemed to help out with communication via Omniauth and Google's API)
Monkey-patch removing SSLv2, SSLv3 from the list of verification methods. When I attempt this in the console on Heroku's server, it appears to work well enough for GET methods, but appears ignore the adjustments completely when attempting to Run Net::HTTP::Post.new instead of Net::HTTP::Get.new
Manually overriding the certificate file location. I've specified it to use the authority file of the operating system (which on the Cedar-14 stack is up-to-date), but still no dice.
I have also tried manually specifying in on the Net::HTTP object to use ssl_version="TLSv1_2" with no luck (it even keeps reporting the same SSLv3 related error)
The communication appears to be working just fine when run locally in development (I've used the RVM override method suggested here), but the moment I try things on the Heroku server, I'm out of luck.
UPDATE: It appears this is not working locally either even with the RVM update.
Last, but not least, here is an abstracted variant of the code I'm running:
uri = URI.parse("https://api.mysite.com/api/v1")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == "https")
request = Net::HTTP::Post.new(uri.path, {'Content-Type' =>'application/json'})
request_body = "{\"post_body\": \"data1\"}"
response = http.request(request)
Anyone have any advice on what else I should be looking at?
Heroku can't verify your server's certificate is validly signed by a CA root it recognizes. This can be because either:
Your cert isn't signed by a CA or intermediate (ie, self-signed)
Your cert is signed by a CA that Heroku doesn't know about (unlikely)
The API server isn't providing the correct intermediate certs to help Heroku connect it to a valid CA root. (likely)
Try openssl s_client -showcerts -connect your-api-host.com:443 from your shell. You should see something like:
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = www.coffeepowered.net
verify return:1
You're specifically looking to make sure that all certs in the chain return verify return: 1. If this works from your shell, then your machine likely has root certs installed that your Heroku instance doesn't.
Without knowing exactly what certs your API server is returning, it's hard to answer this definitively, but you probably need to be serving an intermediate cert bundle along with the SSL cert itself. This intermediate cert bundle will be provided by your SSL certificate signer, and can be provided in Apache via SSLCertificateChainFile, or in nginx by concatening the intermediates with your cert (per this documentation).
If you can't alter the configuration of the API server, then your "Manually overriding the certificate file location" solution is probably very close to correct (it's the same thing as the server providing the intermediate cert, except the client does it), but you are likely not providing the correct certificate chain bundle for your API server's certificates. Make sure that you have the correct intermediate certificate chain provided to OpenSSL, and it should work as desired.

SSL connection error in production mode rails 3.2.3 thin server

I have
config.force_ssl = true
in my environment/production.rb file so as to make every request sequre with ssl and https.
I came to know that SSL can't be enabled in development mode. So, I started my thin web server in production mode and when I went to
https://127.0.0.1:3000
it's the same as the development mode(SSL connection error). Tried almost all the links of first 6 pages fetched by google. Anybody have solution to my problem??
P.S. I'm working on windows and I have client authentication certificate.
The problem you described is related to using a self-signed certificate.
SSL certificates relies on a chain of trust, where the root CA's (Certification Authority) are at the top.
To understand more how it works, the Wikipedia entry on SSL provide a good insight. For Self-Signed certificates there's also an entry at Wikipedia.
To solve you issue you can have a self-signed certificate (be aware of the security issues), but your users will be always prompted for an action.
Another option is to apply for a certificate on CertCA since some Linux distributions have them on root CA's.
The last and most reliable option is to acquire a certificate.

APNS setup for the server

I'm trying to setup our APNS server. I was looking at the instructions on this page:
http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12
I'm understanding everything. Problem is that I have a website already SSL enables (SSL terminates at the load balancer) on AWS, following these instructions a while back:
"Public key certificate and private key doesn't match" when using Godaddy issued certificate
The website for APNS is telling me to get a CSR file, etc. But if I already have this SSL certification done, does it mean I have to start from scratch and re-key my key? :( I wasn't able to find information regarding this...
The APNS CSR has nothing to do with any certificates you already have.
You have to create certificates in the developer area of apples websites. You don't install those certificates to the web server... they are only used from the php script on your server to connect to the apple server as a client. Your script has to load them while they run.. but they are not installed in the web server or load balancer.

Grails SSL certificate error

I'm using the acegi security plugin and I run the app -https. The cert is generated but I get a certificate warning when i visit the web page. I have then download the weak ssl plugin and added weakssl.trustAll =true to Config.groovy. But still getting the same warning. Have I left out anything?
The warning is normal. You can just accept the self-signed certificate. The weakssl module allows the Grails server to trust itself even if it provides a self-signed certificate. It has no effect whatsoever on the client. (Think what a horrible security hole it would be if you could just install some code on the server and get a client to accept a self-signed certificate without a warning!)
To solve your problem you need to either
manually tell your browser the certificate is OK by adding the certificate to your truststore
or
get a certificate from a trusted CA (Certificate Authority) a list of trusted CAs is stored in your browser. To get a certififate from a CA you need to proof your identity and pay (a lot) some money.
so I recommend you just accept the untrusted certifcate unless you want to buy a CA certificate.
The config you changed tells only the server to accept all certificates. i.e. if your server is connecting to another server

Resources