-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Enterprise Testing System #463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
|
||
# Disable pipeline for ordinary pushes to the branches | ||
trigger: none | ||
|
||
# To reduce load on the pipeline, enable it only for PRs that affect critical networking code | ||
pr: | ||
branches: | ||
include: | ||
- master | ||
- release/*.* | ||
|
||
paths: | ||
include: | ||
- src/libraries/Common/src/System/Net/* | ||
davidsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- src/libraries/Common/tests/System/Net/* | ||
- src/libraries/Native/Unix/System.Net.Security.Native/* | ||
- src/libraries/System.Net.Http/* | ||
- src/libraries/System.Net.Security/* | ||
|
||
pool: | ||
vmImage: 'ubuntu-16.04' | ||
|
||
variables: | ||
- template: ../variables.yml | ||
- name: enterpriseTestsSetup | ||
value: $(sourcesRoot)/Common/tests/System/Net/EnterpriseTests/setup | ||
- name: containerRunTestsCommand | ||
value: /repo/.dotnet/dotnet msbuild /t:rebuildandtest | ||
- name: containerLibrariesRoot | ||
value: /repo/src/libraries | ||
|
||
steps: | ||
- bash: | | ||
cd $(enterpriseTestsSetup) | ||
docker-compose build | ||
displayName: Build test machine images | ||
env: | ||
DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) | ||
|
||
- bash: | | ||
cd $(enterpriseTestsSetup) | ||
docker-compose up -d | ||
displayName: Start test network and machines | ||
env: | ||
DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) | ||
|
||
- bash: | | ||
docker exec linuxclient bash /setup/test-webserver.sh | ||
davidsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
displayName: Test linuxclient connection to web server | ||
|
||
- bash: | | ||
docker exec linuxclient bash /repo/libraries.sh | ||
displayName: Build product sources | ||
|
||
- bash: | | ||
docker exec linuxclient $(containerRunTestsCommand) $(containerLibrariesRoot)/System.Net.Http/tests/EnterpriseTests/System.Net.Http.Enterprise.Tests.csproj | ||
docker exec linuxclient $(containerRunTestsCommand) $(containerLibrariesRoot)/System.Net.Security/tests/EnterpriseTests/System.Net.Security.Enterprise.Tests.csproj | ||
displayName: Build and run tests | ||
|
||
- bash: | | ||
cd $(enterpriseTestsSetup) | ||
docker-compose down | ||
displayName: Stop test network and machines | ||
env: | ||
DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) | ||
|
||
- task: PublishTestResults@2 | ||
inputs: | ||
testRunner: 'xUnit' | ||
testResultsFiles: '**/testResults.xml' | ||
testRunTitle: 'Enterprise Tests' | ||
mergeTestResults: true | ||
failTaskOnFailedTests: true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
namespace System.Net.Test.Common | ||
{ | ||
public static class EnterpriseTestConfiguration | ||
{ | ||
public const string Realm = "LINUX.CONTOSO.COM"; | ||
public const string NegotiateAuthWebServer = "http://apacheweb.linux.contoso.com"; | ||
|
||
public static bool Enabled => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DOTNET_RUNTIME_ENTERPRISETESTS_ENABLED")); | ||
public static NetworkCredential ValidNetworkCredentials => new NetworkCredential("user1", "password"); | ||
public static NetworkCredential InvalidNetworkCredentials => new NetworkCredential("user1", "passwordxx"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Enterprise Scenario Testing | ||
|
||
## What Are Enterprise Scenarios? | ||
There are many definitions for enterprise scenarios. But generally in terms of how .NET Core networking APIs are used, enterprise scenarios are those networking scenarios that are fundamentally used by businesses (a.k.a enterprises) compared with consumers. As such, they use networking components, protocols, and security authentication mechanisms that are not used by most consumers using their home networking and Internet connections. | ||
|
||
## Networking Components of Enterprise Scenarios | ||
Enterprise scenarios typically see the following kinds of components/protocols/security: | ||
* Although possibly connected to the Internet, most of the networking topology is internal facing. There is use of some internal “directory” service for authentication of connected computers and users. On Windows, this can include Windows Active Directory domains with computers being domain-controllers, domain-joined, or standalone computers. On Linux, this includes Kerberos realms using KDCs and participating member computers. With .NET Core being cross-platform, this now includes connections with multiple domains and realms with various cross trust between them. | ||
* Authentication protocols such as NTLM, Kerberos and Negotiate. These are used more than Basic and Digest. Negotiate/Kerberos requires both client and server computers to be “joined” to a common trusted directory service. | ||
* TLS/SSL extensively used. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Really? TLS always seemed to be a secondary concern for these systems because of their intranet network topology. They also rely on the design of NTLM, Kerberos, and Negotiate to avoid credential theft without the additional overhead of TLS. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the feedback. This document was written to help explain the overall concept of 'enterprise scenarios' to help developers new to the repo and these scenarios. I'll try to revise the text per your feedback. |
||
* The use of proxy servers for HTTP/HTTPS communication. These usually include authenticated proxies where the proxy server demands authentication typically with Negotiate or NTLM authentication schemes. | ||
* Complex DNS architectures using various A and CNAME (alias) records. | ||
* Use of the NegotiateStream class. This is typically seen as part of using WCF client/server architecture. | ||
* Impersonation/Delegation of credentials. This occurs frequently in middle-tier scenarios that involve a client computer talking with a middle-tier computer (such as a web server) which makes an outbound call to another computer such as a database server. In this case, the credentials of the client computer are delegated across the middle-tier computer so that the outbound call to the database server is made in the context of the client’s credentials. | ||
|
||
|
||
## Running the tests | ||
These tests need to be run in the dedicated Enterprise Test environment. This environment can be created on a local dev machine as long as Docker in installed. The enterprise test environment is a collection of Linux docker containers (client and servers) connected on a common docker network. | ||
|
||
Set the DOTNET_RUNTIME_REPO_ROOT environment variable to the path on your dev machine (the host machine) where the repo is installed: | ||
davidsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
``` | ||
# Windows cmd.exe shell example | ||
set DOTNET_RUNTIME_REPO_ROOT=s:\GitHub\runtime | ||
davidsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
```bash | ||
# Linux bash shell example | ||
export DOTNET_RUNTIME_REPO_ROOT=/home/me/GitHub/runtime | ||
``` | ||
|
||
Now you can start up the enterprise system on your dev machine. | ||
|
||
``` | ||
# Build test machine images | ||
cd %DOTNET_RUNTIME_REPO_ROOT%\src\libraries\Common\tests\System\Net\EnterpriseTests\setup | ||
docker-compose build | ||
|
||
# Start up test machines and network | ||
docker-compose up -d | ||
|
||
# Connect to the 'linuxclient' container | ||
docker exec -it linuxclient bash | ||
``` | ||
|
||
At this point, you are in the linuxclient container. It is one "machine" which is part of an enterprise network. | ||
|
||
Now build the repo as you would on a regular dev machine: | ||
|
||
```bash | ||
cd /repo | ||
./libraries.sh | ||
``` | ||
|
||
Now you can run the enterprise tests. Currently, there are tests for System.Net.Http and System.Net.Security. You can run them in the same way you already run tests in the repo. | ||
|
||
|
||
(System.Net.Http example shown) | ||
|
||
```bash | ||
cd /repo/src/libraries/System.Net.Http/tests/EnterpriseTests | ||
/repo/.dotnet/dotnet msbuild /t:rebuildandtest | ||
``` | ||
|
||
You can exit from the container bash shell: | ||
|
||
```bash | ||
exit | ||
``` | ||
|
||
But the containers stay running. You can re-connect to the client again anytime with the same command: | ||
|
||
``` | ||
docker exec -it linuxclient bash | ||
``` | ||
|
||
You can edit source code on your local machine and then rebuild and rerun tests as needed. | ||
|
||
When you are done with the enterprise test network, you can shut it down from your local dev machine. | ||
|
||
``` | ||
cd %DOTNET_RUNTIME_REPO_ROOT%\src\libraries\Common\tests\System\Net\EnterpriseTests\setup | ||
docker-compose down | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
FROM httpd:2.4 | ||
davidsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
COPY ./common/krb5.conf /etc/ | ||
|
||
WORKDIR /setup | ||
COPY ./apacheweb/*.sh ./ | ||
RUN chmod +x *.sh | ||
|
||
# Prevents dialog prompting when installing packages | ||
ARG DEBIAN_FRONTEND=noninteractive | ||
|
||
# Install Kerberos client, apache Negotiate auth plugin, and diagnostics | ||
RUN apt-get update && \ | ||
apt-get install -y --no-install-recommends libapache2-mod-auth-kerb procps krb5-user iputils-ping dnsutils nano | ||
|
||
# Link apache2 kerb module to the right place since the apt-get install puts it in the wrong place for this docker image | ||
RUN ln -s /usr/lib/apache2/modules/mod_auth_kerb.so /usr/local/apache2/modules | ||
|
||
# Modify httpd.conf to add Negotiate auth as required | ||
RUN echo "LoadModule auth_kerb_module modules/mod_auth_kerb.so" >> /usr/local/apache2/conf/httpd.conf && \ | ||
sed -i 's/Require all granted/AuthType Kerberos\nAuthName "Kerberos Login"\nKrbAuthRealm LINUX\.CONTOSO\.COM\nKrb5Keytab \/etc\/krb5\.keytab\nKrbMethodK5Passwd off\nRequire valid-user/' /usr/local/apache2/conf/httpd.conf | ||
davidsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
EXPOSE 80 | ||
|
||
ENTRYPOINT ["/bin/sh", "/setup/run.sh"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/sh | ||
|
||
cp /SHARED/apacheweb.keytab /etc/krb5.keytab | ||
|
||
exec httpd -DFOREGROUND "$@" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[libdefaults] | ||
default_realm = LINUX.CONTOSO.COM | ||
|
||
# The following krb5.conf variables are only for MIT Kerberos. | ||
kdc_timesync = 1 | ||
ccache_type = 4 | ||
forwardable = true | ||
proxiable = true | ||
|
||
# The following libdefaults parameters are only for Heimdal Kerberos. | ||
fcc-mit-ticketflags = true | ||
|
||
[realms] | ||
LINUX.CONTOSO.COM = { | ||
kdc = kdc.linux.contoso.com | ||
admin_server = kdc.linux.contoso.com | ||
} | ||
|
||
[domain_realm] | ||
.linux.contoso.com = LINUX.CONTOSO.COM |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
version: "3.7" | ||
|
||
services: | ||
kdc: | ||
build: | ||
context: ./ | ||
dockerfile: ./kdc/Dockerfile | ||
image: kdc:latest | ||
container_name: kdc | ||
hostname: kdc | ||
domainname: linux.contoso.com | ||
dns_search: linux.contoso.com | ||
volumes: | ||
- shared-volume:/SHARED | ||
networks: | ||
- network1 | ||
|
||
apacheweb: | ||
build: | ||
context: ./ | ||
dockerfile: ./apacheweb/Dockerfile | ||
image: apacheweb:latest | ||
container_name: apacheweb | ||
hostname: apacheweb | ||
domainname: linux.contoso.com | ||
dns_search: linux.contoso.com | ||
volumes: | ||
- shared-volume:/SHARED | ||
networks: | ||
network1: | ||
aliases: | ||
- apache.linux.contoso.com | ||
depends_on: | ||
- kdc | ||
|
||
linuxclient: | ||
build: | ||
context: ./ | ||
dockerfile: ./linuxclient/Dockerfile | ||
image: linuxclient:latest | ||
container_name: linuxclient | ||
hostname: linuxclient | ||
domainname: linux.contoso.com | ||
dns_search: linux.contoso.com | ||
volumes: | ||
- shared-volume:/SHARED | ||
- ${DOTNET_RUNTIME_REPO_ROOT}:/repo | ||
networks: | ||
- network1 | ||
depends_on: | ||
- apacheweb | ||
- kdc | ||
|
||
networks: | ||
network1: | ||
name: linux.contoso.com | ||
|
||
volumes: | ||
shared-volume: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
FROM ubuntu:18.04 | ||
|
||
COPY ./kdc/kadm5.acl /etc/krb5kdc/ | ||
COPY ./kdc/kdc.conf /etc/krb5kdc/ | ||
COPY ./common/krb5.conf /etc/ | ||
|
||
RUN mkdir /SHARED | ||
|
||
WORKDIR /setup | ||
COPY ./kdc/*.sh ./ | ||
RUN chmod +x *.sh | ||
|
||
# Prevents dialog prompting when installing packages | ||
ARG DEBIAN_FRONTEND=noninteractive | ||
|
||
# Install KDC and diagnostic tools | ||
RUN apt-get update && \ | ||
apt-get install -y --no-install-recommends krb5-kdc krb5-admin-server iputils-ping dnsutils nano | ||
|
||
RUN ./setup-kdc.sh | ||
|
||
VOLUME /SHARED | ||
|
||
EXPOSE 88/tcp | ||
EXPOSE 88/udp | ||
|
||
ENTRYPOINT ["/bin/bash", "/setup/run.sh"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# /etc/krb5kdc/kadm5.acl -- Kerberos V5 general configuration. | ||
# | ||
# The user "root/admin" has full permissions | ||
# Other users can inquire or list principals or policies | ||
*/[email protected] * | ||
*/*@LINUX.CONTOSO.COM il |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[kdcdefaults] | ||
kdc_ports = 88 | ||
|
||
[realms] | ||
LINUX.CONTOSO.COM = { | ||
database_name = /var/lib/krb5kdc/principal | ||
admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab | ||
acl_file = /etc/krb5kdc/kadm5.acl | ||
key_stash_file = /etc/krb5kdc/stash | ||
kdc_ports = 88 | ||
max_life = 10h 0m 0s | ||
max_renewable_life = 7d 0h 0m 0s | ||
master_key_type = des3-hmac-sha1 | ||
#supported_enctypes = aes256-cts:normal aes128-cts:normal | ||
default_principal_flags = +preauth | ||
} | ||
|
||
[logging] | ||
default = FILE:/var/log/kerberos/krb5.log | ||
admin_server = FILE:/var/log/kerberos/kadmin.log | ||
kdc = FILE:/var/log/kerberos/krb5lib.log |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/usr/bin/env bash | ||
|
||
service krb5-kdc restart | ||
service krb5-admin-server restart | ||
|
||
cp /setup/*.keytab /SHARED | ||
chmod +r /SHARED/*.keytab | ||
|
||
# Keep the container running | ||
tail -f /dev/null |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Kerbose Logging | ||
mkdir -pv /var/log/kerberos/ | ||
touch /var/log/kerberos/krb5.log | ||
touch /var/log/kerberos/kadmin.log | ||
touch /var/log/kerberos/krb5lib.log | ||
|
||
# Create Kerberos database | ||
kdb5_util create -r LINUX.CONTOSO.COM -P password -s | ||
|
||
# Start KDC service | ||
krb5kdc | ||
|
||
# Add users | ||
kadmin.local -q "add_principal -pw password root/[email protected]" | ||
kadmin.local -q "add_principal -pw password [email protected]" | ||
|
||
# Add SPNs for services | ||
kadmin.local -q "add_principal -pw password HTTP/apacheweb.linux.contoso.com" | ||
kadmin.local -q "add_principal -pw password HOST/linuxclient.linux.contoso.com" | ||
kadmin.local -q "add_principal -pw password HOST/localhost" | ||
kadmin.local -q "add_principal -pw password NEWSERVICE/localhost" | ||
|
||
# Create keytab files for other machines | ||
kadmin.local ktadd -k /SHARED/apacheweb.keytab -norandkey HTTP/apacheweb.linux.contoso.com | ||
kadmin.local ktadd -k /SHARED/linuxclient.keytab -norandkey HOST/linuxclient.linux.contoso.com | ||
kadmin.local ktadd -k /SHARED/linuxclient.keytab -norandkey HOST/localhost |
Uh oh!
There was an error while loading. Please reload this page.