Jump to content
Sign in to follow this  
PunishmentOfLuxury

(Solved) Configuring Apache for PayID

Recommended Posts

Posted (edited)

I'm totally new to Apache, so excuse me if I've made a silly mistake. I am trying to follow Matt Hamilton's example.

I started an AWS EC2 free micro instance, Linux AMI (not Linux 2).

I registered a domain name and pointed it at the public IP of the instance.

Apache installed fine and I was able to get it to serve index.html from /var/www/html folder.

Then I used Letsencrypt Certbot according to this guide to generate certificates. It seemed to work because when I went to https://mydomain and https://www.mydomain I got the padlock icon in my browser, plus the analysis from www.ssllabs.com/ssltest/analyze.html?d=mydomain was A, almost perfect, for both alternative URLs. The .pem files are where they should be.

Then I edited /etc/httpd/conf/httpd.conf. I only quote the sections I edited:

Quote

# Excerpt from Section 1: Global Environment

Listen 80
<VirtualHost InstancePublicIP:80>
    DocumentRoot "/var/www/html"
    ServerName "MYDOMAIN"
    ServerAlias "www.MYDOMAIN"
RewriteEngine on
RewriteCond %{SERVER_NAME} =MYDOMAIN [OR]
RewriteCond %{SERVER_NAME} =www.MYDOMAIN
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,NE,R=permanent]
</VirtualHost>

<VirtualHost InstancePublicIP:443>
    DocumentRoot "/var/www/html"
    ServerName "MYDOMAIN"
    ServerAlias "www.MYDOMAIN"

    Header always set Strict-Transport-Security "max-age=63072000; preload"

    SSLEngine on
    SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
    SSLProtocol All -SSLv2 -SSLv3
    SSLHonorCipherOrder On
    SSLSessionTickets Off

    SSLCertificateFile "/etc/letsencrypt/live/MYDOMAIN/fullchain.pem"
    SSLCertificateKeyFile "/etc/letsencrypt/live/MYDOMAIN/privkey.pem"

    # PayID
RewriteEngine On
    RewriteCond "%{HTTP_ACCEPT}" "application/xrpl-mainnet\+json"
    RewriteRule ^(.+) /.pay/$1.json [L]

</VirtualHost>

# and lower down in Section 2: 'Main' server configuration:

ServerName www.MYDOMAIN:80

UseCanonicalName Off

DocumentRoot "/var/www/html"


#And in folder /var/www/html/.pay I have file payme.json

{
  "addresses": [
    {
      "paymentNetwork": "XRPL",
      "environment": "MAINNET",
      "addressDetailsType": "CryptoAddressDetails",
      "addressDetails": {
        "address": "XVcktW8qazUdTvDnkARrn*******************"
      }
    }
  ],
  "payId": "payme$MYDOMAIN"

}

I set permissions as: sudo chmod 755 /var/www/html/.pay and sudo chmod 644 payme.json

Restarted Apache. Curiously I've now lost SSL for www.mydomain but not for mydomain. SSL Labs shows "Certificate name mismatch" for www.mydomain.

I tried making a Xumm payment to payme$mydomain but the app says "server not found".

Any help gratefully received!!

Edited by PunishmentOfLuxury

Share this post


Link to post
Share on other sites
Posted (edited)

Someone will come along with proper regex, but my pre-coffee glance tells me that the difference btwn your install and Matt's guide's install is that you've switched around ServerName and ServerAlias (www vs non-www)...  I usually handle forcing www/non-www rewrite conditions within htaccess, not httpd.conf, for reasons of permissions - precisely to avoid these situations.  (I wonder if Matt's version is likewise broken, but in the opposite way, or whether he has a redirect setup to force non-www to the www (or perhaps his regex is so good that he handles the www/non-www AND the forced non-ssl to SSL (http -> https) in the same rewritecond?).)

Which is to say, as well, that httpd.conf and .htaccess (hidden) BOTH handle these type of rewrites - and can often conflict - and should be checked for harmony.

Apologies, no :JC_coffee2:

Edited by NightJanitor

Share this post


Link to post
Share on other sites
8 hours ago, NightJanitor said:

Someone will come along with proper regex, but my pre-coffee glance tells me that the difference btwn your install and Matt's guide's install is that you've switched around ServerName and ServerAlias (www vs non-www)...  I usually handle forcing www/non-www rewrite conditions within htaccess, not httpd.conf, for reasons of permissions - precisely to avoid these situations.  (I wonder if Matt's version is likewise broken, but in the opposite way, or whether he has a redirect setup to force non-www to the www (or perhaps his regex is so good that he handles the www/non-www AND the forced non-ssl to SSL (http -> https) in the same rewritecond?).)

Which is to say, as well, that httpd.conf and .htaccess (hidden) BOTH handle these type of rewrites - and can often conflict - and should be checked for harmony.

Apologies, no :JC_coffee2:

Thanks. I see what you mean about my having the server name and alias swapped cf. Matt. But his .pem files are in his www.HISDOMAIN folder whereas mine are in my MYDOMAIN folder. This arrangement of mine could be the consistency of tiny minds, and entirely irrelevant to the problem, or crucial - I'll wait for further input :)

I didn't know about .htaccess, will check it out.

Share this post


Link to post
Share on other sites
Posted (edited)
19 hours ago, PunishmentOfLuxury said:

RewriteEngine on
RewriteCond %{SERVER_NAME} =MYDOMAIN [OR]
RewriteCond %{SERVER_NAME} =www.MYDOMAIN
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,NE,R=permanent]

What's that supposed to do, exactly?  Even if it made sense to intercept both the version you seem to prefer AND the version you seem to not prefer (for rewriting), that L flag means "LAST" (which tells RewriteEngine to not process any further rewrites).  (Also, you're forcing a rewrite even when it's "not necessary" - which may make things loopy...)

Just comment out anything you did, anywhere, having to do with www/non-www and go from there...

(and if that doesn't work, doublecheck docroot and consider a rewritebase statement... but, please, eliminate some variables of "what it might be," if you want continued at-a-distance-haven't-really-done-this-for-years diagnostic help, for which I surely hope luxury will be my punishment.)

(Another thing to keep in mind with mod_rewrite is that one usually needs to use the [NC] flag to cover case mismatch - just in Case.)

IF you want to try the following code (regex) to handle the www or non-www redirect/rewrite, here's a version that looks for NON-SSL:
 

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.payid\.org$ [NC]
RewriteRule ^(.*)$ https://www.payid.org/$1 [L,R=301]

I believe - but do not guarantee - that you can safely strip out just the three W characters to force the opposite behavior, that is:  to force www.yourdomain.com to be rewritten as simply yourdomain.com - this code is perhaps more safely dropped into .htaccess in html root, where it will only affect that directory and any subdirectories, rather than its being applied globally (and the L flag will be appropriate if it's via .htaccess and 301 is just shorthand for "permanent" redirect).  It might wonk out, on some flavors, when the WWW is stripped from the second rewrite condition (and then loop).  There are a million ways to do www/non-www rewrites/redirects, which is why I suggest handling those only after you've stopped handling them however you're currently doing so (such that it is possible to see if that's what causing things to go sideways).

(Also, if it's not clear, these days I talk a lot more about coding than actually coding... so, I wish us both luck and hope I don't break anything too badly.)

:)

Edited by NightJanitor
catchall + example + catchall example + catchall disclaimer

Share this post


Link to post
Share on other sites

Thanks again @NightJanitor - it will take a fair bit more learning on my part before I can understand everything you wrote. But I have made some progress.

I started over with a fresh AWS AMI Linux 2 instance (as opposed to Linux 1 first time around). The installs of Apache and Certbot went much more smoothly than before. I got the required SSL certificates and all was good with https access to mydomain and www.mydomain. SSL Labs gave an A rating for both.

That was before I fiddled with httpd.conf. I tried adding the code as listed in post #1, but it broke SSL again. Then I inspected /etc/letsencrypt/options-ssl-apache.conf and replaced the SSL configuration in httpd.conf to mirror it:

Quote

    SSLEngine on
    SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA3$
    SSLHonorCipherOrder     off
    SSLSessionTickets Off

Tested again with my browsers - padlocks everywhere - yes!! SSL Labs now gives me A+ for both my domain and www.mydomain. It's allowing TLS 1.2 only.

However, testing with Xumm, I still can't get the PayID section to work.

I'm not sure how the rewrite code got into <VirtualHost InstancePublicIP:80>, I don't remember putting it there. I think Certbot did that. I wouldn't have thought it would affect Xumm because the PayID protocol mandates SSL and isn't going to be polling port 80. The other content there came from Let's Encrypt with Certbot on Amazon Linux 2:

Quote

Edit the main Apache configuration file, /etc/httpd/conf/httpd.conf. Locate the "Listen 80" directive and add the following lines after it, replacing the example domain names with the actual Common Name and Subject Alternative Name (SAN).

<VirtualHost *:80>
    DocumentRoot "/var/www/html"
    ServerName "example.com"
    ServerAlias "www.example.com"
</VirtualHost>

Anyway, I then commented out all the rewrite lines in the current Listen 80 section, leaving the code directly above, but nothing changed - SSL still good, PayID no joy.

I can't find .htaccess anywhere (using ls -a). It's not in /var/www/html. I guess your distro is different.

Share this post


Link to post
Share on other sites

No play yet with payid - can't help you there.  But did see that it might require a dns record, ergo, a propagation delay?  Have never played with certbot, but quick goog says check /etc/apache2/sites-enabled and /sites-available to see if there are any more unexpected rewrites being dropped in (000-default.conf or 000-default-le-ssl.conf) that would be a problem for you whenever you attempt to address the www/non-www stuff (and make it the way you want) again, later on.  Tapping out for now - but I'll revisit.

Share this post


Link to post
Share on other sites
1 hour ago, PunishmentOfLuxury said:

According to https://docs.payid.org/payid-headers there seems to be a syntax error in "%{HTTP_ACCEPT}" "application/xrpl-mainnet\+json". There should be no backslash according to the official site. I deleted it but my PayID still doesn't work in Xumm, nor in Gatehub.

Hi! The backslash in there is needed as it is a regular expression, and + means something specific in regexes (matches one or more of the previous item).

I don't see anything obvious otherwise in your setup.

Someone has created a validator tool, you can try at: https://payidvalidator.com/

-Matt

Share this post


Link to post
Share on other sites
Posted (edited)
1 hour ago, NightJanitor said:

No play yet with payid - can't help you there.  But did see that it might require a dns record, ergo, a propagation delay?  Have never played with certbot, but quick goog says check /etc/apache2/sites-enabled and /sites-available to see if there are any more unexpected rewrites being dropped in (000-default.conf or 000-default-le-ssl.conf) that would be a problem for you whenever you attempt to address the www/non-www stuff (and make it the way you want) again, later on.  Tapping out for now - but I'll revisit.

Those highlighted folders are not present on my AWS instance.

47 minutes ago, hammertoe said:

Hi! The backslash in there is needed as it is a regular expression, and + means something specific in regexes (matches one or more of the previous item).

I don't see anything obvious otherwise in your setup.

Someone has created a validator tool, you can try at: https://payidvalidator.com/

-Matt

Thanks, Matt. I restored the backslash and tried the validator. The results are very disappointing :(

Quote

Validation Results
Score: 0%
CHECK    VALUE    RESULT    MESSAGE
Status Code    404    Fail    
Header Check / Access-Control-Allow-Origin        Fail    The header could not be located in the response.
Header Check / Access-Control-Allow-Methods        Fail    The header could not be located in the response.
Header Check / Access-Control-Allow-Headers        Fail    The header could not be located in the response.
Header Check / Access-Control-Expose-Headers        Fail    The header could not be located in the response.

(Your own PayID address is given a score of 44% by the validator.)

Seems like the protocol is not reading the files. What permissions should I set for the .pay folder and the payme.json file? I have 755 and 644 respectively.

Edited by PunishmentOfLuxury

Share this post


Link to post
Share on other sites
Posted (edited)

Some progress: I thought maybe I had too strict <Directory> rules in httpd.conf. I loosened them for the directory .../mydomain/.pay with "Require all granted" and now I can see the listing of the directory, and can view files payme.json and test.html, in a web browser.

But the PayID validator says exactly the same as it did before - a 404.

Matt's address returns HTTP Status Code 200 (meaning "The resource has been fetched and is transmitted in the message body."). Why am I getting a 404 if the json file is where it should be and readable according to my browser? :scratch_one-s_head:

(Matt's address also fails all of the Header Checks, but there is extra content listed after that relating to the retrieved file.)

Edited by PunishmentOfLuxury

Share this post


Link to post
Share on other sites

I think your problem is the lack of CORS support. In-browser tools (including the PayID validator, it seems) can't make calls to other websites unless the other website specifically allows them to. This is a protection in browsers against scripts being injected in one website to pull data off another site. The XRP Ledger toml file has the same requirement. The way to fix it is probably similar for PayID.

You should add this line to your httpd.conf, maybe in the <VirtualHost InstancePublicIP:443> stanza?

Header set Access-Control-Allow-Origin "*"

 

Share this post


Link to post
Share on other sites
6 hours ago, mDuo13 said:

I think your problem is the lack of CORS support. In-browser tools (including the PayID validator, it seems) can't make calls to other websites unless the other website specifically allows them to. This is a protection in browsers against scripts being injected in one website to pull data off another site. The XRP Ledger toml file has the same requirement. The way to fix it is probably similar for PayID.

You should add this line to your httpd.conf, maybe in the <VirtualHost InstancePublicIP:443> stanza?


Header set Access-Control-Allow-Origin "*"

 

Thanks, yes I have now included that line, plus a few others under the <Directory /> section. I followed the guidelines in Set CORS (Cross-Origin Resource Sharing) Headers and these instructions Setting CORS (cross-origin resource sharing) on Apache with correct response headers allowing everything through.

The great news is, I got rid of all the CORS issues flagged by the PayIDValidator. BUT I still get a 404:

I also tried the testing script outlined on the first link above and loaded it into my browser. Looking in the console, I see:

Quote

mydomain/payme:1 Failed to load resource: the server responded with a status of 404 (Not Found)

PayID_test.html:1 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

I'm really puzzled because I can load https://mydomain/.pay/payme.json in my browsers, but somehow it's not accessible to the PayID protocol. :scratch_one-s_head:

So, I turned my attention to the Apache RewriteRule as shown by Matt:

Quote

# PayID
    RewriteEngine On
    RewriteCond "%{HTTP_ACCEPT}" "application/xrpl-mainnet\+json"
    RewriteRule ^(.+) /.pay/$1.json [L]

I tested the Rewrite Rule line only with this helpful resource: Test your htaccess rewrite rules. Https://mydomain/payme maps correctly to .../mydomain/.pay/payme.json

So now I suspect the RewriteCond is not working correctly. Or I'm doing something really stupid. Been struggling for with this for days. :wacko:

Screenshot from 2020-06-26 14-05-27.png

Share this post


Link to post
Share on other sites

Success!! I solved the problem by moving from AWS to GCP. Google Cloud enables TLSv1.3 whereas AWS is only on v1.2. It may also be necessary to enable HTTP2, but not sure about that.

The CORS headers were not the problem. In fact, the new configuration still fails the payidvalidator test (not with a 404, but 0 error code), but the payme$mydomain address resolves fine with Xumm. :biggrin:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...