I am developing a Self-hosted .Net Core Rest API to be hosted in Docker Container in Service Fabric. I am unable to configure to SSL/Https in Service Fabric. Http seems to work. I am using HttpSys as web server, not Kestrel since I read it is not recommended option for services without reverse proxy(like IIS).
Here is the web server code snippet.
return WebHost.CreateDefaultBuilder(args)
.UseApplicationInsights()
.UseStartup<Startup>()
.UseHttpSys(
options =>
{
options.Authentication.Schemes = AspNetCore.Server.HttpSys.AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
}
)
.Build();
Here is ServiceManifest.xml Endpoints snippet.
<Endpoints>
<Endpoint Name="ServiceEndpoint" Protocol="http" Port="80" />
<Endpoint Name="ServiceEndpointHttps" Protocol="https" Port="443" Type="Input" CertificateRef="SSLCertificate" />
</Endpoints>
Here is ApplicationManifest EnvironmentVariable snippet.
<EnvironmentVariable Name="ASPNETCORE_URLS" Value="https://*:443/;http://*:80/"/>
Here is ApplicationManifest.xml Policies snippet.
<Policies>
<ContainerHostPolicies CodePackageRef="Code">
<RepositoryCredentials AccountName="accountname" Password="password" PasswordEncrypted="false" />
<PortBinding ContainerPort="80" EndpointRef="ServiceEndpoint"/>
<PortBinding ContainerPort="443" EndpointRef="ServiceEndpointHttps"/>
</ContainerHostPolicies>
<EndpointBindingPolicy CertificateRef="SSLCertificate" EndpointRef="ServiceEndpointHttps" />
</Policies>
Here is ApplicationManifest.xml Certificates snippet.
<Certificates>
<EndpointCertificate Name="SSLCertificate" X509FindValue="cert thumbprint"/>
</Certificates>
Initially, I had issues with Certificate deployment when I had SSL certificate only in CurrentUser\My Certificate Store. I resolved it after deploying the certificate in LocalMachine\My Certificate Store. With this fix, Service seems to be working only with HTTP protocol in Port 80, not with HTTPS protocol in Port 443.
Service Fabric Explorer doesn't show any error and no errors in Events Log also. I am facing this issue in both Local Service Fabric and in Azure Service Fabric instances.
Any thoughts/pointers on this would be appreciated.
Using Service Fabric for container and https could follow this doc.
It will inject the certificate into the container as environment variables.
But for linux clusters, there is a problem. The Certificates_ServicePackageName_CodePackageName_CertName_PEM and Certificates_ServicePackageName_CodePackageName_CertName_PrivateKey represented files are having the exact same content.
I'm waiting for the Azure China supporter for further clarification on this, not sure if it's a China specific problem.
Related
I have a asp.net core application hosted in docker . The docker file looks like this
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
LABEL cmbappname="autocomplete"
ARG source
WORKDIR /cmbapp
ADD ${source} .
ENV APP_UTILS=C:\\app
VOLUME ${APP_UTILS}
HEALTHCHECK --retries=5 --interval=100s --start-period=10s CMD curl --fail http://localhost || exit 1
ENTRYPOINT ["dotnet", "MyBus.AutoApi.dll"]
EXPOSE 80
EXPOSE 443
the docker image in hosted in service fabric which has a service manifest like this
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="AutoApiPkg"
Version="1.0.0"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<!-- This is the name of your ServiceType.
The UseImplicitHost attribute indicates this is a guest service. -->
<StatelessServiceType ServiceTypeName="AutoApiType" UseImplicitHost="true" />
</ServiceTypes>
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
<ContainerHost>
<ImageName>autoApi</ImageName>
</ContainerHost>
</EntryPoint>
<!-- Pass environment variables to your container: -->
<EnvironmentVariables>
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="Debug" />
<EnvironmentVariable Name="ASPNETCORE_URLS" Value="https://*:443/;http://*:80/;https://*:54100/;http://*:54200/"/>
</EnvironmentVariables>
</CodePackage>
with the container policies in the Applicaiton manifest
<Policies>
<ContainerHostPolicies CodePackageRef="Code" AutoRemove="false" UseDefaultRepositoryCredentials="false" ContainersRetentionCount="2" RunInteractive="true">
<!-- See https://aka.ms/I7z0p9 for how to encrypt your repository password -->
<PortBinding ContainerPort="443" EndpointRef="AutApiTypeEndpoint" />
<PortBinding ContainerPort="80" EndpointRef="LocalAutApiTypeEndpoint" />
<RepositoryCredentials AccountName="[AzureContainerUserName]" Password="[AzureContainerPassword]" PasswordEncrypted="false"/>
<HealthConfig IncludeDockerHealthStatusInSystemHealthReport="true" RestartContainerOnUnhealthyDockerHealthStatus="false" />
</ContainerHostPolicies>
</Policies>
the application runs and is functional without the enviornment variable "ASPNETCORE_URLS"
but when adding the env variable its not functional nor is it reachable.
debugging the container gives the following error logs
Unable to start Kestrel. System.InvalidOperationException: Unable to
configure HTTPS endpoint. No server certificate was specified, and the
default developer certificate could not be fo und or is out of date.
Get a certificate, for example by using Letsencrypt [example], or use a self-signed certificate (for testing).
Use a volume to attach the certificate file to your container.
Use an environment variable to indicate where the certificate is stored:
ASPNETCORE_Kestrel__Certificates__Default__Path=certificate.pfx
Use another environment variable to provide the password to allow access to the private key:
ASPNETCORE_Kestrel__Certificates__Default__Password="****"
More info here.
I am trying to wire up Azure Key Vault in my ASP.NET (.Net Framework) MVC Web App using Visual Studio 2017 Community 15.7.5 Connected Service targeting .Net 4.7.2.
It adds a configBuilder with the name AzureKeyVault with an attribute called vaultName that throws a "The 'vaultName' attribute is not allowed." warning.
When I run the application I get an error that the configBuilders attribute on the appsetting tag is not good like so:
I am using the following package versions which are all current:
<package id="Microsoft.Azure.KeyVault" version="3.0.0" targetFramework="net472" />
<package id="Microsoft.Azure.KeyVault.WebKey" version="3.0.0" targetFramework="net472" />
<package id="Microsoft.Azure.Services.AppAuthentication" version="1.0.3" targetFramework="net472" />
There is an update to Microsoft.Azure.Services.AppAuthentication but it is a preview and it caused dependency issues with other packages.
tldr; - you probably don't have the appropriate permissions to access the key vault.
In currently released versions of the .Net framework, detailed errors about config builders are not always easily discoverable in the ASP.NET yellow screen. We have changes in vNext to address this issue, but it is currently a problem for 4.7.1/2. For the time being, if you create a simple console app to read appSettings with the same config builder configuration, you should see more exception information in the stack that gets spit out.
Based on the yellow screen you posted though I would guess (and its really just an educated guess based on past reports and nothing specific in your case) you are running into an authentication issue in the Microsoft.Azure.Services.AppAuthentication library. When running in Visual Studio, that library can use your personal credentials to access the key vault. If deployed in Azure, they use a different magic technology to authenticate the application to the key vault. If you want to eliminate the "magic" and take more control over this, you can specify more detailed connection information with the 'connectionString' attribute. There is more information as well as a link to connection string details on our GitHub page (MicrosoftConfigurationBuilders).
As for the "The 'vaultName' attribute is not allowed." warning... it's just a warning. The .xsd that VS uses to validate configuration was not correctly updated to allow random attributes on configBuilder definitions. We hope to address this in a future VS release around the time that the next framework ships.
Steve Molloy was correct in that the Configuration Error was a red herring. I created a console app and the error messages were much better but they still required some investigation. Here's my Console App Code and packages:
static void Main(string[] args)
{
var azureServiceTokenProvider = new AzureServiceTokenProvider
(azureAdInstance:"https://InsertAADSubscriptionName.onmicrosoft.com/");
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var secret = keyVaultClient.GetSecretAsync(
"https://InsertKeyVaultName.vault.azure.net", "InsertSecretYouWantBack").GetAwaiter().GetResult();
}
<packages>
<package id="Microsoft.Azure.KeyVault" version="3.0.0" targetFramework="net472" />
<package id="Microsoft.Azure.KeyVault.WebKey" version="3.0.0" targetFramework="net472" />
<package id="Microsoft.Azure.Services.AppAuthentication" version="1.0.3" targetFramework="net472" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.8" targetFramework="net472" />
<package id="Microsoft.Rest.ClientRuntime" version="2.3.13" targetFramework="net472" />
<package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.15" targetFramework="net472" />
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net472" />
</packages>
I put a breakpoint on the last bracket and kept looking for my secret value in the variable secret. I kept getting the following error indicating that Azure AD wasn't able to authenticate my local environment and return an access token.
Parameters: Connection String: [No connection string specified],
Resource: https://vault.azure.net,
Authority: https://login.windows.net/47c8ce10-a05d-4880-9e92-0c2d2c00dc88.
Exception Message: Tried the following 4 methods to get an access token,
but none of them worked.
Parameters: Connection String: [No connection string specified],
Resource: https://vault.azure.net,
Authority: https://login.windows.net/47c8ce10-a05d-4880-9e92-0c2d2c00dc88.
Exception Message: Tried to get token using Managed Service Identity.
Unable to connect to the Managed Service Identity (MSI) endpoint.
Please check that you are running on an Azure resource that has MSI setup.
Parameters: Connection String: [No connection string specified],
Resource: https://vault.azure.net,
Authority: https://login.windows.net/47c8ce10-a05d-4880-9e92-0c2d2c00dc88.
Exception Message: Tried to get token using Visual Studio.
Access token could not be acquired.
Parameters: Connection String: [No connection string specified],
Resource: https://vault.azure.net,
Authority: https://login.windows.net/47c8ce10-a05d-4880-9e92-0c2d2c00dc88.
Exception Message: Tried to get token using Azure CLI. Access token could
not be acquired. ERROR: Please run 'az login' to setup account.
Parameters: Connection String: [No connection string specified],
Resource: https://vault.azure.net,
Authority: https://login.windows.net/47c8ce10-a05d-4880-9e92-0c2d2c00dc88.
Exception Message: Tried to get token using Active Directory Integrated
Authentication. Access token could not be acquired. get_user_name_failed:
Failed to get user nameInner Exception : No mapping between account names
and security IDs was done
The problem was that since I was running the app locally I needed to be logged in to Azure CLI locally. To do this: first install Azure CLI on your machine, then go to a CMD or a PowerShell prompt and type az login and follow the instructions returned.
This did the trick; the console app was able to get an access token.
I tried it on my web app in the original question above and it worked as expected.
We have a setting defined in our Azure Cloud Service (csdef)
<ConfigurationSettings>
<Setting name="CDN" />
</ConfigurationSettings>
And it's value in the cscfg file
<ConfigurationSettings>
<Setting name="CDN" value="az12345.vo.msecnd.net" />
</ConfigurationSettings>
And in order for to work "outside" of Azure we have this in the web.config
<add key="CDN" value="localcdn" />
When the cloud service is deployed into Azure the value for CDN is "localcdn" and NOT the value that is in the cscfg file "az12345.vo.msecnd.net".
We have other cloud services with exactly the same setting which are resolved correctly, but this service refuses to.
My understanding from https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.cloudconfigurationmanager.getsetting.aspx is that it will get the value from the cscfg when in Azure and web/app.config when it's not.
We are using Microsoft Azure Configuration Manager 3.1.0
Issue caused by Role Environment erroring
We are trying to consume web service from orbeon client code. Everything works fine with one way SSL however we now wish to call the web service using 2 way SSL. We are able to call the web service using 2 way SSL successfully using the Apache CXF framework using Java code.
I followed the steps outlined in the Orbeon Wiki.
Changes made in properties-local.xml
<property as="xs:anyURI"
name="oxf.http.ssl.keystore.uri"
value="/apps/property/ClientStore.jks"/>
<property as="xs:string"
name="oxf.http.ssl.keystore.password"
value="password"/>
<property as="xs:anyURI"
name="oxf.url-rewriting.service.base-uri"
value="http://localhost:8085/Orbeon"/>
<property as="xs:anyURI"
name="oxf.fr.persistence.exist.uri"
value="http://localhost:8085/fr/service/exist"/>
<property as="xs:anyURI"
name="oxf.fr.persistence.exist.exist-uri"
value="http://localhost:8085/exist/rest/db/orbeon/fr"/>
After implementing the changes outlined above we are getting the exception below:
ERROR XFormsServer - xforms-submit-error - setting throwable {throwable:
"javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:390)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:488)
at org.apache.http.conn.scheme.SchemeSocketFactoryAdaptor.connectSocket(SchemeSocketFactoryAdaptor.java:62)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148
Java start up options are:
-Djavax.net.ssl.trustStorePassword=password
-Djavax.net.ssl.keyStore=/apps/property/DMClientStore.jks
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=/apps/property/trustkeystore.jks
Questions:
Are these properties sufficient for enabling 2 way SSL?
For Apache CXF we need to provide two keystores, one with the client certificate and a truststore. Where do we configure both of these keystores for Orbeon?
I have an Ubuntu server with Elasticsearch, MongoDB, and Graylog2 running in Azure, and I have an asp.net mvc4 application I am trying to send logs from. (I am using Gelf4Net / Log4Net as the logging component). To cut to the chase, nothing is being logged.
(skip to the update to see what is wrong)
The setup
1 Xsmall Ubuntu VM running the needed software for graylog2
everything is running as a daemon
1 Xsmall cloud service with the MVC4 app (2 instnaces)
A virtual network setup so they can talk.
So what have I tried?
From the linux box the follow command will cause a message to be logged echo "<86>Dec 24 17:05:01 foo-bar CRON[10049]: pam_unix(cron:session):" |
nc -w 1 -u 127.0.0.1 514
I can change the IP address to use the public IP and it works fine as well.
using this powershell script I can log the same message from my dev machine as well as the production web server
Windows firewall turned off and it still doesn't work.
I can log to a FileAppender Log4Net, so I know Log4Net is working.
tailing the graylog2.log shows nothing of interest. Just a few warning about my plugin directory
So I know everything is working, but I can't get the Gelf4Net appender to work. I'm a loss here. Where can I look? Is there something I am missing
GRAYLOG2.CONF
#only showing the connection stuff here. If you need something else let me know
syslog_listen_port = 514
syslog_listen_address = 0.0.0.0
syslog_enable_udp = true
syslog_enable_tcp = false
web.config/Log4Net
//application_start() has log4net.Config.XmlConfigurator.Configure();
<log4net >
<root>
<level value="ALL" />
<appender-ref ref="GelfUdpAppender" />
</root>
<appender name="GelfUdpAppender" type="Gelf4net.Appender.GelfUdpAppender, Gelf4net">
<remoteAddress value="public.ip.of.server"/>
<remotePort value="514" />
<layout type="Gelf4net.Layout.GelfLayout, Gelf4net">
<param name="Facility" value="RandomPhrases" />
</layout>
</appender>
</log4net>
update
for some reason it didn't occur to me to run graylog in debug mode :) Doing so shows this message.
2013-04-09 03:00:56,202 INFO : org.graylog2.inputs.syslog.SyslogProcessor - Date could not be parsed. Was set to NOW because allow_override_syslog_date is true.
2013-04-09 03:00:56,202 DEBUG: org.graylog2.inputs.syslog.SyslogProcessor - Skipping incomplete message.
So it is sending an incomplete message. How can I see what is wrong with it?
I was using the wrong port (DOH!)
I should have been using the port specified in graylog2.config / gelf_listen_port = 12201
so my web.config/log4net/gelf appender should have had
<appender name="GelfUdpAppender" type="Gelf4net.Appender.GelfUdpAppender, Gelf4net">
...
<remotePort value="12201" />
...
</appender>
For anyone who may have the same problem, make sure Log4Net reloads the configuration after you change it. I don't have it set to watch the config file for changes, so it took me a few minutes to realize that I was using the wrong port. When I changed it from 514 to 12201 the first time, messages still weren't getting though. I had to restart the server for Log4Net to pick up the new config, and then it started to work.