WSO2 API Manager and Apache Reverse Proxy
This is an end-to-end article describing how to use Apache as a reverse proxy server for WSO2 API Manager (Single node all-in-one).
Join the DZone community and get the full member experience.
Join For FreeThis is an end-to-end article describing how to use Apache as a reverse proxy server for WSO2 API Manager (Single node all-in-one). The main focus of the article is installing and configuring the Apache server. For this tutorial, I have used Linux Mint (Ubuntu) as my operational system.
Before We Proceed
Please download the following software for the tutorial:
1. WSO2 API Manager: It can be downloaded from this site.
2. JDK 8
Installing and Configuring Apache
For this tutorial, I am using the Apache/2.4.29 (Ubuntu). The installation is straight forward.
$ sudo apt update
$ sudo apt install apache2
For details of the installation, you can check out this article. In Ubuntu, it will be installed in the following location:
$ /etc/apache2
Below is a directory structure of the Apache server:
Troubleshooting
If the server is not running, execute the following command to run the server:
$ sudo apachectl -k start
You might get an error (if unlucky) saying that either port 80 or 443 is being used. To solve this, either you can find the process who is using those ports and kill them or simply change the default ports of Apache server. So, how to do it?
Navigate to the ports.conf file and open it using:
$ sudo vi ports.conf
Here you can change the ports. After changing the port, execute the command to start the server. After successfully starting the server, you should get the below log. (Don't worry about the warning)
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
httpd (pid 6208) already running
Verify The Server
Open a browser and navigate the link, http://localhost:8888. Note that I have changed the HTTP port number to 8888. You should see a webpage as shown below.
The page itself gives an overview of the Apache server. Also, execute the https://localhost and you should get the same page.
At this moment, we have a running Apache server.
Important Commands of Apache server
To check which modules are loaded by Apache, execute the following command.
$ sudo apachectl -M
To install a module, execute the following command.
$ sudo a2enmod ssl # To install ssl module. You can add more modules
# separated by space.
To enable/disable a site, execute the following command.
$ sudo a2ensite proxy.com # Enables the site proxy.com
$ sudo a2dissite proxy.com # Disables the site proxy.com
Deployment Architecture
Below is a simple deployment architecture.
Configure Host Names
Let's define two hosts in the /etc/hosts file, as shown below.
#Apache
127.0.0.1 proxy.com
#WSO2
127.0.0.1 wso2.apim.com
Configuring SSL VirtualHost in Apache
Navigate to the following directory and you should see the default virtual host configurations.
$ /etc/apache2/sites-available
There is the default https://localhost configuration in this file default-ssl.conf. You can copy this configuration file and modify it to create your own. For this tutorial, let's create a configuration file called proxy.com.conf. Note that it can be any name of your choice and the file name must end with a .conf extension.
Here is the configuration file.
<VirtualHost *:443>
DocumentRoot /var/www/proxy.com
ServerName proxy.com
ServerAdmin webmaster@proxy.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
ProxyPreserveHost On
ProxyRequests Off
SSLProxyEngine on
SSLProxyCheckPeerCN Off
SSLProxyCheckPeerExpire Off
### Management URIs
ProxyPass /store https://wso2.apim.com:9443/store
ProxyPassReverse /store https://wso2.apim.com:9443/store
ProxyPass /publisher https://wso2.apim.com:9443/publisher
ProxyPassReverse /publisher https://wso2.apim.com:9443/publisher
ProxyPass /carbon https://wso2.apim.com:9443/carbon
ProxyPassReverse /carbon https://wso2.apim.com:9443/carbon
### Images
ProxyPass /registry https://wso2.apim.com:9443/registry
ProxyPassReverse /registry https://wso2.apim.com:9443/registry
### Gateway URIs
ProxyPass /pizzashack/ https://wso2.apim.com:8243/pizzashack/
ProxyPassReverse /pizzashack/ https://wso2.apim.com:8243/pizzashack/
</VirtualHost>
Note: Note the mapping to /pizzashack API.
Let's create a directory for the document root.
$sudo mkdir /var/www/proxy.com
Note that I am using the default SSL certificates provided by Apache. Feel free to create your own certificates.
Enable the Site
Execute the following command to enable the site.
$ sudo a2ensite proxy.com
Then restart Apache
$ sudo apachectl -k restart
Configure WSO2 API Manager
Do the following changes in the WSO2 API Manager.
wso2am-2.6.0/repository/conf/carbon.xml
<HostName>wso2.apim.com</HostName>
<MgtHostName>wso2.apim.com</MgtHostName>
wso2am-2.6.0/repository/conf/tomcat/catalina-server.xml
Add proxyPort in the connectores.
<!--
optional attributes:
proxyPort="80"
-->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
port="9763"
redirectPort="9443"
proxyPort="80"
bindOnInit="false"
maxHttpHeaderSize="8192"
acceptorThreadCount="2"
maxThreads="250"
minSpareThreads="50"
disableUploadTimeout="false"
connectionUploadTimeout="120000"
maxKeepAliveRequests="200"
acceptCount="200"
server="WSO2 Carbon Server"
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/javascript,application/x-javascript,application/javascript,application/xml,text/css,application/xslt+xml,text/xsl,image/gif,image/jpg,image/jpeg"
URIEncoding="UTF-8"/>
<!--
optional attributes:
proxyPort="443"
Added sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" for poodle vulnerability fix
-->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
port="9443"
proxyPort="443"
bindOnInit="false"
sslProtocol="TLS"
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
maxHttpHeaderSize="8192"
acceptorThreadCount="2"
maxThreads="250"
minSpareThreads="50"
disableUploadTimeout="false"
enableLookups="false"
connectionUploadTimeout="120000"
maxKeepAliveRequests="200"
acceptCount="200"
server="WSO2 Carbon Server"
clientAuth="false"
compression="on"
scheme="https"
secure="true"
SSLEnabled="true"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/javascript,application/x-javascript,application/javascript,application/xml,text/css,application/xslt+xml,text/xsl,image/gif,image/jpg,image/jpeg"
keystoreFile="${carbon.home}/repository/resources/security/wso2carbon.jks"
keystorePass="wso2carbon"
URIEncoding="UTF-8"/>
wso2am-2.6.0/repository/conf/api-manager.xml
Add the GatewayEndpoint.
<APIGateway>
<!-- The environments to which an API will be published -->
<Environments>
<!-- Environments can be of different types. Allowed values are 'hybrid', 'production' and 'sandbox'.
An API deployed on a 'production' type gateway will only support production keys
An API deployed on a 'sandbox' type gateway will only support sandbox keys
An API deployed on a 'hybrid' type gateway will support both production and sandbox keys. -->
<!-- api-console element specifies whether the environment should be listed in API Console or not -->
<Environment type="hybrid" api-console="true">
<Name>Production and Sandbox</Name>
<Description>This is a hybrid gateway that handles both production and sandbox token traffic.</Description>
<!-- Server URL of the API gateway -->
<ServerURL>https://localhost:${mgt.transport.https.port}${carbon.context}services/</ServerURL>
<!-- Admin username for the API gateway. -->
<Username>${admin.username}</Username>
<!-- Admin password for the API gateway.-->
<Password>${admin.password}</Password>
<!-- Endpoint URLs for the APIs hosted in this API gateway.-->
<GatewayEndpoint>https://proxy.com</GatewayEndpoint>
<!-- Endpoint of the Websocket APIs hosted in this API Gateway -->
<GatewayWSEndpoint>ws://${carbon.local.ip}:9099</GatewayWSEndpoint>
</Environment>
</Environments>
</APIGateway>
wso2am-2.6.0/repository/deployment/server/jaggeryapps/publisher/site/conf/site.json
"reverseProxy" : {
"enabled" : true, // values true , false , "auto" - will look for X-Forwarded-* headers
"host" : "proxy.com", // If reverse proxy do not have a domain name use IP
"context":"/publisher",
"regContext":""
}
wso2am-2.6.0/repository/deployment/server/jaggeryapps/store/site/conf/site.json
"reverseProxy" : {
"enabled" : true, // values true , false , "auto" - will look for X-Forwarded-* headers
"host" : "proxy.com", // If reverse proxy do not have a domain name use IP
"context":"/store",
"regContext":""
}
wso2am-2.6.0/repository/deployment/server/jaggeryapps/admin/site/conf/site.json
"reverseProxy" : {
"enabled" : true, // values true , false , "auto" - will look for X-Forwarded-* headers
"host" : "proxy.com", // If reverse proxy do not have a domain name use IP
"context":"/admin",
"regContext":""
}
And that's it. Now you should be able to view the /publisher, /store and /carbon at the following URLs:
The GW should be able to make calls at the following URL:
Conclusion
In this article, I have explained how to use a single VirtualHost in Apache to proxy requests to WSO2 API Manager. However, it's advisable to use two separate hosts i.e one for Management consoles (publisher, store, admin, carbon) and another for the Gateway.
Thanks.
Opinions expressed by DZone contributors are their own.
Comments