I'm setting up a Service Fabric application which contains:
an Nginx instance as frontend (single instance, port 80)
some applications written with Asp.net core (1 website, some API services) (multiple instances, dynamic port)
a Gateway service for address resolution (single instance, port 8081)
For nginx, I'm using a solution available as Nuget package.
The gateway and, in general, the example to run .NET core app have been taken here
It is suggested by the .NET core team itself to host applications behind a real web server liken nginx.
Therefore I'd like to deploy my Service Fabric application with an instance of nginx as entry point, which redirects to the Gateway service, which will do the service resolution for the replicated stateless services.
My question is about the address that I need to use in the nginx.conf to point to the Gateway address. While trying locally, I can use the local address 127.0.0.1 and it works as expected, but what happens if on a real cluster my Nginx and Gateway instances are deployed to different machines?
This is my application manifest:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="SFApplicationType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="NginxPoC_InstanceCount" DefaultValue="1" />
<Parameter Name="Gateway_InstanceCount" DefaultValue="1" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="NginxPoCPkg" ServiceManifestVersion="1.0.0" />
<Policies>
<RunAsPolicy CodePackageRef="Code" UserRef="Admin" EntryPointType="All" />
</Policies>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Gateway" ServiceManifestVersion="1.0.0" />
</ServiceManifestImport>
<DefaultServices>
<Service Name="NginxPoC">
<StatelessService ServiceTypeName="NginxPoCType" InstanceCount="[NginxPoC_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="Gateway">
<StatelessService ServiceTypeName="GatewayType" InstanceCount="[Gateway_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
<Principals>
<Users>
<User Name="Admin">
<MemberOf>
<SystemGroup Name="Administrators" />
</MemberOf>
</User>
</Users>
</Principals>
</ApplicationManifest>
and this is my current nginx.conf file:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:8081;
}
}
Update 2016-10-09
As requested in the discussion, I've created a test project here. Every contribute to the project is welcome.
f you deploy the nginx and gateway service to all nodes (InstanceCount = -1) you should be good. If the gateway service is down on one node, you would of course not be able to forward the request from nginx to a gateway service on another node. For this, you need the nginx service to look-up the gateway service.
You can get the service endpoint address for the gateway using a REST call: https://msdn.microsoft.com/en-us/library/azure/dn707638.aspx
Related
This has been asked before but I am completely stuck and nothing so far has worked for me that has been listed in other questions. While this refers to Identity Server I think i have missed something in setting SSL up.
I have setup as follows (this is with IIS express not full IIS):
Identity Server app: auth.testhost.com:44373/core
Web API service: https://localhost:44356/
I get the error in the title on the line:
app.UseIdentityServerBearerTokenAuthentication(options);
This is basically requesting some open configuration options from the server at auth.testhost.com:44373/core/.well-known/openid-configuration.
My options are:
Authority = "https://auth.testhost.com:44373/core",
RequiredScopes = new List<string>() { "api" }
In some examples I see a client id and secret, but they are not available in the options for me: is this a problem?
If you need to see any identity server options please say and I'll post.
I ran the following command to create a cert:
makecert.exe -r -pe -n "CN=auth.testhost.com" -b 01/01/2000 -e 01/01/2036 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -len 2048
This generated the certificate, which I then exported to Trusted Root Certification Authorities.
From what I can tell, the SSL port bindings should be handled by Visual Studio as I am using IIS Express. Below are the bindings it has:
<site name="Authenticator_V2" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="c:\users\user\documents\visual studio 2015\Projects\Authenticator_V2\Authenticator_V2" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:49755:localhost" />
<binding protocol="https" bindingInformation="*:44373:localhost" />
<binding protocol="https" bindingInformation="*:44373:auth.testhost.com" />
</bindings>
</site>
<site name="APIClient2" id="7">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Users\user\documents\visual studio 2015\Projects\Authenticator_V2\APIClient2" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:53812:localhost" />
<binding protocol="https" bindingInformation="*:44356:localhost" />
</bindings>
</site>
This is my hosts file:
127.0.0.1 localhost
127.0.0.1 hybrid.testhost.com
127.0.0.1 auth.testhost.com
When I go to https://auth.testhost.com:44373/ I still have a red line through my protocol. I assume this means something has not been configured correctly still. I am using Chrome and clicking on the certificate gives:
"Your connection to this site is not private."
Details:
SHA-1 Certificate
The certificate for this site expires in 2017 or later, and the certificate chain contains a certificate signed using SHA-1.
View certificate
Certificate Error
There are issues with the site's certificate chain (net::ERR_CERT_COMMON_NAME_INVALID).
I looked at the ERR_CERT_COMMON_NAME_INVALID error and it seems that is a chrome bug. However my error is being thrown from the web services server trying to connect to the authentication server so I think I can ignore this one???
I also ran netsh to check there was a cert binding set up:
netsh http show sslcert ipport=0.0.0.0:44373
SSL Certificate bindings:
-------------------------
IP:port : 0.0.0.0:44373
Certificate Hash : HAS ODD HASH - REMOVED
Application ID : {HAS GUID - REMOVED}
Certificate Store Name : MY
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
Reject Connections : Disabled
At this point a noticed this hash is not the right one for my certificate. It is for the IIS Express localhost. I found this link: IdentityServer: The remote certificate is invalid according to the validation procedure and copied the steps to move the localhost certificate into the Trusted Root Certification Authorities but unfortunately I still have the error. I now am not sure what else to do.
Scope Configuration:
new Scope
{
Name = "api",
DisplayName = "Can call API",
Enabled = true,
Type = ScopeType.Resource
//ScopeSecrets = new List<Secret> { }
}
All my clients have this scope.
Thanks
This issue was fixed by upgrading all but IdentityModel.Jwt to latest versions, which gave the options to set the Certificate and Issuer Name on the bearer options. Both of these were required to be set for the error to go away
I've got an app which is running on JBoss 7. Its URL is http://localhost:8080/archive/app. How can I make it look http://localhost:8080/app or http://localhost/app?
PS. /archive means archive.war
1) Remove the welcome root. In the standalone.xml set:
<virtual-server name="default-host" enable-welcome-root="false">
2) Set the context root. In your archive.war add a jboss-web.xml file in the WEB-INF folder:
<?xml version="1.0"?>
<jboss-web>
<context-root>/</context-root>
</jboss-web>
3) Set the http port to 80. In the standalone.xml change:
<socket-binding name="http" port="8080"/> to <socket-binding name="http" port="80"/>
Remember that if your server runs on a Linux machine it must be launched by root in order to use ports under 1024. In that case you can redirect from 80 to 8080 by means of iptables without the need to change the standalone.xml socket-binding
I have followed scot's article on how to enable default ports (80 and 443) for http and https respectively. I have followed each step to the letter and in the end IIS express sytem tray shows me that site is running on following urls
Only thing i have done differently is to use netsh>advfirewall>firewall context because it was telling me that netsh firewall is deprecated. I used following command to allow port 80 through firewall
netsh advfirewall firewall add rule name="Open Port 80" dir=in action=allow protocol=TCP localport=80
Here is the relevant site section from applicationhost.config file of IIS Express
<site name="SSLTest" id="4">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="G:\Adeel\SSLTest\SSLTest" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:51518:localhost" />
<binding protocol="https" bindingInformation="*:44301:localhost" />
<binding protocol="http" bindingInformation="*:80:mhlabs" />
<binding protocol="https" bindingInformation="*:443:mhlabs" />
</bindings>
</site>
Edit: The problem is that when i browse to http:/mhlabs or https:/mhlabs it does not work. I get not found page of the browser. how can i get around that.
Edit2: Ok, as a first step, i would like to forget ssl and just reserve a url for test-one on port 80 and run my site on this url. The logical steps that come to mind is that i reserve a url using netsh http add urlacl url=http://test-one:80/ user=everyone and add this entry in bindings section of applicationhost.config file. i also allowed port 80 through firewall but the whole thing does not seem to work for me. Any ideas?
Are you starting iis express from command line or using WebMatrix?
If you are not starting it from command line, try following steps and see if there are any binding errors.
start command prompt, goto iis express installation folder '%programfiles%\iis express'
run following command
iisexpress.exe /site:SSLTest
If there are any bindings registration failure, you would see some error message.
If there is any error for 'mhlabs' binding registration, make sure your URL reservation is correct. URL reservation command should like below
netsh http add urlacl url=http://mhlabs:80/ user=everyone
I installed RhodeCode 1.2.2 at a Windows 2008R2 (64Bit) box.
I had setup a IIS 7 as a Proxy Server (Application Request Routing + URL Rewrite) for RhodeCode running at 127.0.0.1:5000.
The Repository is reachable via "https://subdomain.domain.de".
At the repository summary, the Clone url points to:
https://[username]#127.0.0.1:5000/SomeProject
At the client side, I can clone the repository when replacing the
"127.0.0.1:5000" with "subdomain.domain.de".
For sure I would like that RhodeCode displays the Proxy url
("subdomain.domain.de") instead of the 127.XXX...
I search the web up and down and the only thing I found, was that
Apache has a "ProxyPreserveHost On" setting, which does the trick. However
I didn't found anything like that for IIS.
Is there somewhere a setting within the "production.ini" where I can
define the proxy url?
Or does someone found the well hidden setting within the IIS?
Any help is much appreciated :-)
thanks for your answer! I already use the ARR and setup the reverse proxy, I can access RhodeCode via the proxy. However, it looks like that the HTTP_HOST value is not forwarded to paster.
Within the IIS, I setup the following server variables and set them within the reverse proxy rule:
<set name="HTTP_HOST" value="[subdomain.domain.de]" />
<set name="HTTP_X_FORWARDED_SERVER" value="[subdomain.domain.de]" />
<set name="HTTP_X_ORIGINAL_HOST" value="[subdomain.domain.de]" />
<set name="HTTP_X_HTTP_HOST" value="[subdomain.domain.de]" />
<set name="HTTP_X_URL_SCHEME" value="https" />
but that have no affect at all.
At the linked previously answer, he suggested to copy these variable values back to the HTTP_HOST (within tomcat, should be paster in my case). That looks a bit overkilled to me, in comparsion to a simple "ProxyPreserveHost On" within apache. I have the feeling that I missed something here.
Cheers,
Sörnt
Itvan is correct, that will work.
Uncommenting the clone_uri will leave the default clone_uri. You can force the clone_uri to use your domain by having that line:
clone_uri = {scheme}://{user}{pass}[subdomain.domain.de]{path}
PS: Works on version 1.3.6
I'm working on out reverse proxying over https for rhodecode with apache on centos6 right now.
For Apache, the configuration noted by marcin of rhodecode fame is:
<VirtualHost *:80>
ServerName hg.myserver.com
ServerAlias hg.myserver.com
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
#important !
#Directive to properly generate url (clone url) for pylons
ProxyPreserveHost On
#rhodecode instance
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
#to enable https use line below
#SetEnvIf X-Url-Scheme https HTTPS=1
</VirtualHost>
For the IIS equivilent of ProxyPreserveHost, see Application Request Routing, which was provided in a previously answer by a MSFT MVP.
The http server is actually python paste's httpserver, so referring to the python paste documentation for httpserver (egg#Paste:http is familiar right), there is no proxy configuration. You will have to reverse proxy in IIS (source)
I am unsure why marcin has opted to advise setting up the reverse proxy versus utilizing paste's httpserver support for https; but having IIS field the requests, and binding paste's httpserver to 127.0.0.1 is likely best choice.
I've just installed RhodeCode 1.3.3 and got into this issue. You can edit this line in configuration file to make it work:
## overwrite schema of clone url
## available vars:
## scheme - http/https
## user - current user
## pass - password
## netloc - network location
## path - usually repo_name
#clone_uri = {scheme}://{user}{pass}{netloc}{path}
clone_uri = {scheme}://{user}{pass}yourdomain.com{path}
I have a program running on a remote host that I need to connect to, handshake, then listen for messages. I have setup the following camel route:
<route>
<from uri="netty:tcp://localhost:50001?decoders=#decoders&sync=false" />
<bean ref="TransformMessage" method="inboundDecoder" />
<to uri="eventadmin:messages/aacus/inbound" />
</route>
<route>
<from uri="eventadmin:messages/aacus/outbound" />
<bean ref="TransformMessage" method="outboundEncoder" />
<to uri="netty:tcp://192.168.0.111:50001?allowDefaultCodec=false&sync=false" />
</route>
My question is how do I make this work? If I establish the route using
<from uri="netty:tcp://192.168.0.111:50001?decoders=#decoders&sync=false" />
it fails with a binding error.
How can I setup the connection to respond on a specific port without modifying the server?
This is not possible with either camel-mina nor camel-netty at this time of writing. A consumer can only bind to a local server. There is a JIRA ticket at Apache to implement such a new feature for the future. https://issues.apache.org/jira/browse/CAMEL-1077
Use the following workaround:
Instead ob 192.168.0.111 use localhost.
Then install "socat" and start it as follows
socat -s -u tcp4:192.168.0.111:50001 tcp4:localhost:50001
This will Tunnel your remote connection to the local service you created with camel/netty.