diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 00000000..c77a4e98 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,42 @@ +--- +name: Bug +about: Create a bug report to help us improve +title: '' +labels: component/demos, kind/bug +assignees: '' + +--- + +## Summary +A clear and concise description of what the bug is. + +## Steps to Reproduce +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +## Expected Results +A clear and concise description of what you expected to happen. + +## Actual Results (including error logs, if applicable) +A clear and concise description of what actually did happen. + +## Reproducible + * [ ] Always + * [ ] Sometimes + * [ ] Non-Reproducible + +## Version/Tag number +What version of the product are you running? Any version info that you can share is helpful. +For example, you might give the version from Docker logs, the Docker tag, a specific download URL, +the output of the `/info` route, etc. + +## Environment setup +Can you describe the environment in which this product is running? Is it running on a VM / in a container / in a cloud? +Which cloud provider? Which container orchestrator (including version)? +The more info you can share about your runtime environment, the better we may be able to reproduce the issue. + +## Additional Information +Add any other context about the problem here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..3451e260 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,27 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: kind/enhancement, component/demos +assignees: '' + +--- + +## Is your feature request related to a problem? Please describe. + +A clear and concise description of what the problem is. Ex.`I would like to see [...] because [...]`. +Please include the intended use case and what the feature would improve on so that we can prioritize +the feature accordingly. + +## Describe the solution you would like + +A clear and concise description of what the desired end result(s) would be. + +## Describe alternatives you have considered + +A clear and concise description of any alternative solutions or features that may be related to this that +you have considered. + +## Additional context + +Add any other context information about the feature request here. \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..6fe0f5c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +cli_cache/* +**/cli_cache/* +*.tar + +tools/simple-certificates/certificates/* +.DS_Store + +logs/* +**/logs/* + +# Editor files +*.sw[po] +vm/.vagrant + +# JMeter results +tools/performance-tests/jmeter/jmeter_reports/* +tools/performance-tests/jmeter/jmeter.log + +**/backup/* + +files/haproxy/master/haproxy.cfg + +# Generated Certificates +**/certificates/ca-chain.pem +**/certificates/dap_follower/ +**/certificates/dap_master/ +**/certificates/intermediate_ca/ +**/certificates/root_ca/ + +# Versions plugin backup file (use git history instead) +**/pom.xml.versionsBackup \ No newline at end of file diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 00000000..cf0d1db8 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,222 @@ +title = "Secretless Broker gitleaks config" + +# This is the config file for gitleaks. You can configure gitleaks what to search for and what to whitelist. +# If GITLEAKS_CONFIG environment variable +# is set, gitleaks will load configurations from that path. If option --config-path is set, gitleaks will load +# configurations from that path. Gitleaks does not whitelist anything by default. +# - https://www.ndss-symposium.org/wp-content/uploads/2019/02/ndss2019_04B-3_Meli_paper.pdf +# - https://github.com/dxa4481/truffleHogRegexes/blob/master/truffleHogRegexes/regexes.json +[[rules]] +description = "AWS Client ID" +regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' +tags = ["key", "AWS"] + +[[rules]] +description = "AWS Secret Key" +regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' +tags = ["key", "AWS"] + +[[rules]] +description = "AWS MWS key" +regex = '''amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}''' +tags = ["key", "AWS", "MWS"] + +[[rules]] +description = "PKCS8" +regex = '''-----BEGIN PRIVATE KEY-----''' +tags = ["key", "PKCS8"] + +[[rules]] +description = "RSA" +regex = '''-----BEGIN RSA PRIVATE KEY-----''' +tags = ["key", "RSA"] + +[[rules]] +description = "SSH" +regex = '''-----BEGIN OPENSSH PRIVATE KEY-----''' +tags = ["key", "SSH"] + +[[rules]] +description = "PGP" +regex = '''-----BEGIN PGP PRIVATE KEY BLOCK-----''' +tags = ["key", "PGP"] + +[[rules]] +description = "Facebook Secret Key" +regex = '''(?i)(facebook|fb)(.{0,20})?(?-i)['\"][0-9a-f]{32}['\"]''' +tags = ["key", "Facebook"] + +[[rules]] +description = "Facebook Client ID" +regex = '''(?i)(facebook|fb)(.{0,20})?['\"][0-9]{13,17}['\"]''' +tags = ["key", "Facebook"] + +[[rules]] +description = "Facebook access token" +regex = '''EAACEdEose0cBA[0-9A-Za-z]+''' +tags = ["key", "Facebook"] + +[[rules]] +description = "Twitter Secret Key" +regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{35,44}['\"]''' +tags = ["key", "Twitter"] + +[[rules]] +description = "Twitter Client ID" +regex = '''(?i)twitter(.{0,20})?['\"][0-9a-z]{18,25}['\"]''' +tags = ["client", "Twitter"] + +[[rules]] +description = "Github" +regex = '''(?i)github(.{0,20})?(?-i)['\"][0-9a-zA-Z]{35,40}['\"]''' +tags = ["key", "Github"] + +[[rules]] +description = "LinkedIn Client ID" +regex = '''(?i)linkedin(.{0,20})?(?-i)['\"][0-9a-z]{12}['\"]''' +tags = ["client", "Twitter"] + +[[rules]] +description = "LinkedIn Secret Key" +regex = '''(?i)linkedin(.{0,20})?['\"][0-9a-z]{16}['\"]''' +tags = ["secret", "Twitter"] + +[[rules]] +description = "Slack" +regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?''' +tags = ["key", "Slack"] + +[[rules]] +description = "EC" +regex = '''-----BEGIN EC PRIVATE KEY-----''' +tags = ["key", "EC"] + +[[rules]] +description = "Generic API key" +regex = '''(?i)(api_key|apikey)(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' +tags = ["key", "API", "generic"] + +[[rules]] +description = "Generic Secret" +regex = '''(?i)secret(.{0,20})?['|"][0-9a-zA-Z]{32,45}['|"]''' +tags = ["key", "Secret", "generic"] + +[[rules]] +description = "Google API key" +regex = '''AIza[0-9A-Za-z\\-_]{35}''' +tags = ["key", "Google"] + +[[rules]] +description = "Google Cloud Platform API key" +regex = '''(?i)(google|gcp|youtube|drive|yt)(.{0,20})?['\"][AIza[0-9a-z\\-_]{35}]['\"]''' +tags = ["key", "Google", "GCP"] + +[[rules]] +description = "Google OAuth" +regex = '''(?i)(google|gcp|auth)(.{0,20})?['"][0-9]+-[0-9a-z_]{32}\.apps\.googleusercontent\.com['"]''' +tags = ["key", "Google", "OAuth"] + +[[rules]] +description = "Google OAuth access token" +regex = '''ya29\.[0-9A-Za-z\-_]+''' +tags = ["key", "Google", "OAuth"] + +[[rules]] +description = "Heroku API key" +regex = '''(?i)heroku(.{0,20})?['"][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}['"]''' +tags = ["key", "Heroku"] + +[[rules]] +description = "MailChimp API key" +regex = '''(?i)(mailchimp|mc)(.{0,20})?['"][0-9a-f]{32}-us[0-9]{1,2}['"]''' +tags = ["key", "Mailchimp"] + +[[rules]] +description = "Mailgun API key" +regex = '''(?i)(mailgun|mg)(.{0,20})?['"][0-9a-z]{32}['"]''' +tags = ["key", "Mailgun"] + +[[rules]] +description = "Password in URL" +regex = '''[a-zA-Z]{3,10}:\/\/[^\/\s:@]{3,20}:[^\/\s:@]{3,20}@.{1,100}\/?.?''' +tags = ["key", "URL", "generic"] + +[[rules]] +description = "PayPal Braintree access token" +regex = '''access_token\$production\$[0-9a-z]{16}\$[0-9a-f]{32}''' +tags = ["key", "Paypal"] + +[[rules]] +description = "Picatic API key" +regex = '''sk_live_[0-9a-z]{32}''' +tags = ["key", "Picatic"] + +[[rules]] +description = "Slack Webhook" +regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}''' +tags = ["key", "slack"] + +[[rules]] +description = "Stripe API key" +regex = '''(?i)stripe(.{0,20})?['\"][sk|rk]_live_[0-9a-zA-Z]{24}''' +tags = ["key", "Stripe"] + +[[rules]] +description = "Square access token" +regex = '''sq0atp-[0-9A-Za-z\-_]{22}''' +tags = ["key", "square"] + +[[rules]] +description = "Square OAuth secret" +regex = '''sq0csp-[0-9A-Za-z\\-_]{43}''' +tags = ["key", "square"] + +[[rules]] +description = "Twilio API key" +regex = '''(?i)twilio(.{0,20})?['\"][0-9a-f]{32}['\"]''' +tags = ["key", "twilio"] + +[whitelist] +files = [ + ".gitleaks.toml", + "demos/cluster/files/certs/*", # sample certs for demos + "demos/simple-cluster/files/certs/*", # sample certs for demos + "demos/aws-authentication/jason-conjur-test.pem", # sample cert for aws auth + "demos/ldap-integration/certs/*" # sample certs for ldap demo +] +regexes = [ +] +commits = [ + "406dc7268f9b014bb8bc8acc7854a18114ac5346", # old commit with vagrant priv key + "6e9dcb3698a8a339c7112cf395cf7c2389d4150d" # old commit with vagrant priv key +] + +# Additional Examples + +# [[rules]] +# description = "Generic Key" +# regex = '''(?i)key(.{0,6})?(:|=|=>|:=)''' +# entropies = [ +# "4.1-4.3", +# "5.5-6.3", +# ] +# entropyROI = "line" +# filetypes = [".go", ".py", ".c"] +# tags = ["key"] +# severity = "8" +# +# +# [[rules]] +# description = "Generic Key" +# regex = '''(?i)key(.{0,6})?(:|=|=>|:=)''' +# entropies = ["4.1-4.3"] +# filetypes = [".gee"] +# entropyROI = "line" +# tags = ["key"] +# severity = "medium" + +# [[rules]] +# description = "Any pem file" +# filetypes = [".key"] +# tags = ["pem"] +# severity = "high" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..7c0a67db --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,16 @@ +# Contributing + +For general contribution and community guidelines, please see the [community repo](https://github.com/cyberark/community). + +## Contributing Workflow + +1. [Fork the project](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) +2. [Clone your fork](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository) +3. Make local changes to your fork by editing files +3. [Commit your changes](https://help.github.com/en/github/managing-files-in-a-repository/adding-a-file-to-a-repository-using-the-command-line) +4. [Push your local changes to the remote server](https://help.github.com/en/github/using-git/pushing-commits-to-a-remote-repository) +5. [Create new Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) + +From here your pull request will be reviewed and once you've responded to all +feedback it will be merged into the project. Congratulations, you're a +contributor! diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..8bf8d957 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem 'cucumber' +gem 'rspec-expectations' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..d93683bd --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,73 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (7.0.3.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + builder (3.2.4) + concurrent-ruby (1.1.10) + cucumber (5.2.0) + builder (~> 3.2, >= 3.2.4) + cucumber-core (~> 8.0, >= 8.0.1) + cucumber-create-meta (~> 2.0, >= 2.0.2) + cucumber-cucumber-expressions (~> 10.3, >= 10.3.0) + cucumber-gherkin (~> 15.0, >= 15.0.2) + cucumber-html-formatter (~> 9.0, >= 9.0.0) + cucumber-messages (~> 13.1, >= 13.1.0) + cucumber-wire (~> 4.0, >= 4.0.1) + diff-lcs (~> 1.4, >= 1.4.4) + multi_test (~> 0.1, >= 0.1.2) + sys-uname (~> 1.2, >= 1.2.1) + cucumber-core (8.0.1) + cucumber-gherkin (~> 15.0, >= 15.0.2) + cucumber-messages (~> 13.0, >= 13.0.1) + cucumber-tag-expressions (~> 2.0, >= 2.0.4) + cucumber-create-meta (2.0.4) + cucumber-messages (~> 13.1, >= 13.1.0) + sys-uname (~> 1.2, >= 1.2.1) + cucumber-cucumber-expressions (10.3.0) + cucumber-gherkin (15.0.2) + cucumber-messages (~> 13.0, >= 13.0.1) + cucumber-html-formatter (9.0.0) + cucumber-messages (~> 13.0, >= 13.0.1) + cucumber-messages (13.2.1) + protobuf-cucumber (~> 3.10, >= 3.10.8) + cucumber-tag-expressions (2.0.4) + cucumber-wire (4.0.1) + cucumber-core (~> 8.0, >= 8.0.1) + cucumber-cucumber-expressions (~> 10.3, >= 10.3.0) + cucumber-messages (~> 13.0, >= 13.0.1) + diff-lcs (1.4.4) + ffi (1.13.1) + i18n (1.12.0) + concurrent-ruby (~> 1.0) + middleware (0.1.0) + minitest (5.16.2) + multi_test (0.1.2) + protobuf-cucumber (3.10.8) + activesupport (>= 3.2) + middleware + thor + thread_safe + rspec-expectations (3.10.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.10.0) + rspec-support (3.10.0) + sys-uname (1.2.2) + ffi (~> 1.1) + thor (1.2.1) + thread_safe (0.3.6) + tzinfo (2.0.5) + concurrent-ruby (~> 1.0) + +PLATFORMS + ruby + +DEPENDENCIES + cucumber + rspec-expectations + +BUNDLED WITH + 2.1.4 diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..1f8d71fc --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,38 @@ +#!/usr/bin/env groovy + +pipeline { + agent { label 'executor-v2' } + + options { + ansiColor('xterm') + timestamps() + buildDiscarder(logRotator(daysToKeepStr: '30')) + } + + parameters { + string(name: 'FROM', description: 'Version to upgrade from', defaultValue: '') + string(name: 'TO', description: 'Version to upgrade to', defaultValue: '') + } + + stages { + stage('Run upgrade test') { + when { + allOf { + expression { env.FROM } + expression { env.TO } + } + } + steps { + sh './bin/upgrade-test "${FROM}" "${TO}"' + } + } + } + + post { + always { + script { + cleanupAndNotify(currentBuild.currentResult, '#conjur-core') + } + } + } +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..f8e0d1b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2020 CyberArk Software Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 3409f16f..f9074080 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,222 @@ -# misc-util -Miscellaneous utilities that make it easier to make, manage, and run demos +# Conjur Intro +Tools and scripts utilities that make it easier to make, manage, and run demos + +## Demos + +- [AWS Cluster](demos/aws-cluster/README.md) +- [Conjur Cluster](demos/cluster/README.md) +- [Certificate Authority](demos/certificate-authority/mutual-tls/README.md) +- [LDAP Sync and Authentication](demos/ldap-integration/README.md) + +## Tools +- [Generate Signed Certificates](tools/simple-certificates/) +- [JMeter Performance Tests](tools/performance-tests/) + +## CLI Tools + +This project includes a CLI which simplifies the process of running a variety of scenarios. + +### Workflow Examples + +Deploy a master auto-failover cluster (behind L4 load balancer). + +```sh +$ bin/dap --provision-master +$ bin/dap --provision-standbys +$ bin/dap --enable-auto-failover +``` + +Given the above, to add a follower (behind L7 load balancer), add data, and validate retrieval: +```sh +$ bin/dap --provision-follower +$ bin/api --load-sample-policy-and-values +$ bin/api --fetch-secrets +``` + +Next, let's trigger an auto-failover event: +```sh +$ bin/dap --trigger-failover +``` + +Upgrade and rebuild cluster: +```sh +$ bin/dap --upgrade-master +$ bin/dap --provision-standbys --version +$ bin/dap --enable-auto-failover +$ bin/dap --provision-follower --version +``` + +and finally, validate: + +```sh +$ bin/api --fetch-secrets +``` + +### Working with Podman + +The project is enabled to work with Podman instead of Docker. +To use Podman the above commands can be replaced as follows: + +```sh +$ bin/podman-dap --provision-master +$ bin/podman-dap --provision-standbys +$ bin/podman-dap --enable-auto-failover +``` + +Similarly bin/api and bin/cli can be replaced with bin/podman-api and bin/podman-cli. + +To connect to the UI in the browser, use ports 10443(through HA proxy) or 10444(Conjur) +*** + +### bin/dap +`bin/dap` provides a dead simple mechanism for starting DAP in a variety of configurations and workflows. It provides visibility into the commands required to perform various workflows. + +#### Flags +|Flag|Type|Outcome|Notes| +|-|-|-|-| +|--create-backup|action|• Creates a backup|Requires configured master| +|--dry-run|configuration|Only print configuration commands| +|--enable-auto-failover|action|• Configures Master cluster with auto-failover|Requires configured master and standbys| +|--generate-dh|configuration|• Disables the mounting of pre-generated DH params inside the master so they're generated on the fly| +|--help||Shows all available arguments|| +|--import-custom-certificates|action|• Imports pre-generated 3rd-party certificates|Requires configured master| +|--promote-standby|action|• Stops the current master
• Promotes a standby| Requires configured standbys and no auto-failover| +|--provision-follower|action|• Removes follower if present
• Starts a DAP container and a Layer 7 load balancer
• Generates a follower seed
• Configures follower|Requires configured master| +|--provision-master|action|• Starts a DAP container and Layer 4 load balancer
• Configures with account `demo` and password `MySecretP@ss1`|| +|--provision-standbys|action|• Removes standbys if present
• Starts two DAP containers
• Generates standby seed files
• Configures standbys
• Enable Synchronous Standby|Requires configured master| +|--restore-from-backup|action|• Removes auto-failover (if enabled)
• Stops and renames master
• Starts new DAP container
• Restores master from backup|Requires a previously created backup| +|--stop|action|Stops and removes all containers|| +|--trigger-failover|action|• Stops current master|Requires an auto-failover cluster| +|--trust-follower-proxy|action|• Adds Follower load balancer as a trusted proxy|Requires configured follower| +|--upgrade-master ``|action|• Removes auto-failover (if enabled)
• Generates a backup
• Stops and removes master
• Starts new DAP container
• Restores master from backup|Requires configured master| +|--version ``|configuration|Version of DAP to use (defaults to latest)| + +### bin/api + +`bin/api` enables some common policy and API flows. + +#### Flags + +|Flag|Type|Outcome|Notes| +|-|-|-|-| +|--against-master|configuration|Runs read actions against the master|| +|--authenticate-user|action|• Authenticates with default user and password
• Displays the resulting authentication token|| +|--fetch-secrets|action|• Authenticates
• Retrieves variable values|Run against follower unless `--against-master` flag is present| +|--load-policy|action|• Authenticates
• Loads policy|Run against master| +|--load-policy-and-values|action|• Authenticates
• Loads policy and variable values|Run against master, equivalent to running '--load-policy' and '--set-secrets'| +|--password ``|configuration|Uses a non-default password for authentication|| +|--set-secrets|action|• Authenticates
• Sets variable values|Requires `--load-policy` before running| +|--user ``|configuration|Uses a non-default (`admin`) user for authentication|| + +## Start a single DAP instance + +To start a single DAP instance: + +```sh +$ bin/dap --provision-master +``` + +This instance runs behind an HAProxy load balancer and is available at: [https://localhost]. Login: + +- Account `demo` +- User: `admin` +- Password: `MySecretP@ss1` + +## Start a DAP Cluster with Follower + +To start a basic HA DAP cluster (self-signed certificates, no Master Key encryption) and a Follower: + +```sh +$ bin/dap --provision-master +$ bin/dap --provision-standbys +$ bin/dap --provision-follower +``` + +This instance runs behind an HAProxy load balancer and is available at: [https://localhost]. Login: + +- Account `demo` +- User: `admin` +- Password: `MySecretP@ss1` + +#### Available Flags + +The following flags are available: + +``` +Usage: bin/dap single [options] + + --create-backup Creates a backup|Requires configured master + --dry-run Print configuration commands with executing + --enable-auto-failover Configures Master cluster with auto-failover (Requires configured master and standbys) + --h, --help Shows this help message + --import-custom-certificates Imports pre-generated 3rd-party certificates (Requires configured master) + --promote-standby Stops the current master and promotes a standby (Requires configured standbys and no auto-failover) + --provision-follower Configures follower behind a Layer 7 load balancer (Requires configured master) + --provision-master Configures a DAP Master with account `demo` and password `MySecretP@ss1` behind a Layer 4 load balancer + --provision-standbys Deploys and configures two standbys (Requires configured master) + --restore-from-backup Restores a master from backup|Requires a previously created backup + --stop Stops all containers and cleans up cached files + --trigger-failover Stops current master (Requires an auto-failover cluster) + --trust-follower-proxy Adds Follower load balancer as a trusted proxy (Requires a configured follower) + --upgrade-master Restores master from backup (Requires configured master) + --version Version of DAP to use (defaults to latest build) +``` + +### `bin/cli` +`bin/cli` is a proxy script, sending all subsequent arguments to a Conjur CLI container. This provides a simple mechanism for loading policy and interacting with Conjur. + +#### Loading policy +The policy folder contains sample policy which can be loaded with: +```sh +$ bin/cli conjur policy load --replace root policy/users.yml +$ bin/cli conjur policy load root policy/policy.yml +$ bin/cli conjur policy load staging policy/apps/myapp.yml +$ bin/cli conjur policy load production policy/apps/myapp.yml +$ bin/cli conjur policy load root policy/application_grants.yml +$ bin/cli conjur policy load root policy/hosts.yml +``` + +#### Setting/Retrieving a Variable +``` +bin/cli conjur variable values add production/myapp/database/username my-username +bin/cli conjur variable values add production/myapp/database/password my-password +bin/cli conjur variable values add production/myapp/database/url https://my-database.mycompany.com +bin/cli conjur variable values add production/myapp/database/port 5432 +``` + +#### Validating Packages +This project can also be used to verify PRs, by installing the branch specific package (created by Jenkins). To begin, download the `.deb` package. After starting Conjur, packages can be installed with: + +``` +# Start Conjur +$ bin/dap --provision-master --version 5.11.0 +``` +Next in a new tab: + +``` +$ bin/install ~/Downloads/conjur-ui_2.10.9.1-e389f20_amd64.deb +``` +The install script will install the package into the running Conjur appliance and restart the Conjur service. + +You can view the contents of this package by running: + +``` +$ docker-compose exec conjur-master-1.mycompany.local ls -a /opt/conjur/possum/ +``` + +## Performance Tests +``` +# Start tests +$ ./performance_test/start.sh +``` +More information can be found [here](./performance_test/README.md#jmeter-performance-test) + +## Contributing + +We welcome contributions of all kinds to this repository. For instructions on +how to get started and descriptions of our development workflows, please see our +[contributing guide](CONTRIBUTING.md). + +## License + +This repository is licensed under Apache License 2.0 - see [`LICENSE`](LICENSE) for more details. diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..99ba2ee8 --- /dev/null +++ b/Rakefile @@ -0,0 +1,9 @@ +require 'rubygems' +require 'cucumber' +require 'cucumber/rake/task' +require 'rspec/expectations' + +Cucumber::Rake::Task.new(:features) do |t| + t.cucumber_opts = "--format pretty" # Any valid command line option can go here. + include RSpec::Matchers +end diff --git a/artifacts/api-client/Dockerfile b/artifacts/api-client/Dockerfile new file mode 100644 index 00000000..817d7c31 --- /dev/null +++ b/artifacts/api-client/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine:3 + +RUN apk add --no-cache curl jq diff --git a/artifacts/api-client/api-script b/artifacts/api-client/api-script new file mode 100755 index 00000000..82a5b9fc --- /dev/null +++ b/artifacts/api-client/api-script @@ -0,0 +1,197 @@ +#!/bin/ash -e + +_print_help() { + cat << EOF + +A tool which uses the DAP API to perform various tasks. + +Usage: bin/api [options] + + --against-master Runs command against the master (only relevant if command is an authenticate/read action) + --authenticate-user Login using the default username (admin) and password (MySecretP@ss1) + --enable-seed-service Enables Seed Service for Standbys and Followers + --fetch-secrets Fetches previously set variables (use '--against-master' if only master is available) + -h, --help Shows this help message + --load-policy + --load-sample-policy Loads a default set of policies to mimic a customer experience + --load-sample-policy-and-values Loads policy and sets variable values (equivalent to running '--load-policy' and '--set-secrets') + -p, --password Password used for authentication (default is 'MySecretP@ss1') + --rotate-api-key Rotates the authenticated user's API key + --set-secrets Sets variable values + -u, --user Username to authenticate with (default is 'admin') + --view-roles Displays the user's roles + +EOF + exit +} + +retrieve_authentication_token() { + local user="$1" + # Allow hosts to be used instead of just users + user=$(echo "$user" | sed -e "s/\//%2F/g") + local api_key="$2" + local url="${3:-$URL}" + raw_token="$(curl \ + --silent \ + --insecure \ + --request POST \ + --data $api_key \ + "$url/authn/demo/$user/authenticate")" + token=$(echo -n $raw_token | base64 | tr -d '\r\n') + echo "$token" +} + +authenticate_user() { + local user="$1" + local password="$2" + local url="${3:-$URL}" + api_key="$(curl \ + --silent \ + --insecure \ + --user $user:$password \ + "$url/authn/demo/login")" + token=$(retrieve_authentication_token $user $api_key $url) + echo "$token" +} + +load_policy() { + local namespace="$1" + local policy="$2" + local method="${3:-POST}" + local token=$(authenticate_user $USER $PASSWORD $master_url) + curl --header "Authorization: Token token=\"$token\"" \ + --write-out "\n" \ + --insecure \ + --request "$method" \ + --data "$(cat $policy)" \ + "$master_url/policies/demo/policy/$namespace" +} + +set_variable() { + local variable="$1" + local value="$2" + local token=$(authenticate_user $USER $PASSWORD $master_url) + + curl --header "Authorization: Token token=\"$token\"" \ + --insecure \ + --data "$value" \ + "$master_url/secrets/demo/variable/$variable" +} + +load_default_policy() { + local environments='staging production' + local numbers='1 2 3 4 5 6' + + load_policy 'root' 'policy/modular/root.yml' + + for environment in $environments; do + load_policy $environment 'policy/modular/apps/applications.yml' + for num in $numbers; do + load_policy "$environment/my-app-$num" 'policy/modular/apps/generic-application.yml' + load_policy "$environment/my-app-$num" 'policy/modular/services/pg-database.yml' + load_policy "$environment/my-app-$num" 'policy/modular/pg-entitlement.yml' + done + done + + load_policy 'root' 'policy/delete_policy/base.yml' + load_policy 'delete_branch' 'policy/delete_policy/first_level.yml' 'PUT' + load_policy 'delete_branch/first-level' 'policy/delete_policy/second_level.yml' +} + +delete_policy() { + load_policy 'delete_branch/first-level' 'policy/delete_policy/delete.yml' 'PATCH' +} + +load_default_values() { + local environments='staging production' + local numbers='1 2 3 4 5 6' + + for environment in $environments; do + for num in $numbers; do + set_variable "$environment/my-app-$num/postgres-database/url" "$environment.my-app-$num.staging.mycompany-postgres.com/my-app" + set_variable "$environment/my-app-$num/postgres-database/port" "5432" + set_variable "$environment/my-app-$num/postgres-database/username" "my-app-$num" + set_variable "$environment/my-app-$num/postgres-database/password" "secret-p@ssword-$environment-my-app-$num" + done + done +} + +fetch_secrets() { + local variables="$1" + local token=$(authenticate_user $USER $PASSWORD $URL) + curl --header "Authorization: Token token=\"$token\"" \ + --write-out "\n" \ + --insecure \ + --request GET \ + "$master_url/secrets?variable_ids=$variables" +} + +retrieve_variables() { + secrets="demo:variable:staging/my-app-1/postgres-database/url,demo:variable:staging/my-app-1/postgres-database/port,demo:variable:staging/my-app-1/postgres-database/username,demo:variable:staging/my-app-1/postgres-database/password" + fetch_secrets $secrets +} + +load_policy_and_set_variables() { + load_default_policy + load_default_values +} + +view_policy_members() { + local token=$(authenticate_user $USER $PASSWORD $URL) + curl --header "Authorization: Token token=\"$token\"" \ + --write-out "\n" \ + --insecure \ + --request GET \ + "$master_url/roles/demo/policy/production?members" +} + +view_roles() { + local token=$(authenticate_user $USER $PASSWORD $URL) + curl --header "Authorization: Token token=\"$token\"" \ + --write-out "\n" \ + --insecure \ + --request GET \ + "$master_url/resources/demo" | jq . +} + +rotate_api_key() { + curl --header "Authorization: Token token=\"$token\"" \ + --insecure \ + --request GET \ + "$master_url/resources/demo" +} + +enable_seed_service() { + load_policy 'root' 'policy/seed-service/default.yml' + load_policy 'conjur' 'policy/seed-service/seed.yml' +} + +follower_url='http://conjur-follower.mycompany.local' +master_url='https://conjur-master.mycompany.local' +URL=$follower_url +USER='admin' +PASSWORD='MySecretP@ss1' +cmd='' + +while true ; do + case "$1" in + -u | --user ) shift ; USER=$1 ; shift ;; + -p | --password ) shift ; PASSWORD=$1 ; shift ;; + --authenticate-user ) shift ; cmd="authenticate_user $USER $PASSWORD" ;; + -h | --help ) _print_help ; shift ;; + --patch-policy ) shift ; cmd="load_policy $1 $2 PATCH" ; shift ; shift ;; + --load-policy ) shift ; cmd="load_policy $1 $2" ; shift ; shift ;; + --load-sample-policy-and-values ) shift ; cmd="load_policy_and_set_variables" ;; + --load-sample-policy ) shift ; cmd='load_default_policy' ;; + --delete-policy ) shift; cmd='delete_policy' ;; + --set-secrets ) shift ; cmd='load_default_values' ;; + --against-master ) shift ; URL=$master_url ;; + --fetch-secrets ) shift ; cmd="retrieve_variables" ;; + --view-roles ) cmd="view_roles" ; shift ;; + --rotate-api-key ) cmd="rotate_api_key" ;; + --enable-seed-service ) shift ; cmd='enable_seed_service' ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac +done + +eval $cmd diff --git a/artifacts/certificate-generator/Dockerfile b/artifacts/certificate-generator/Dockerfile new file mode 100644 index 00000000..99108e63 --- /dev/null +++ b/artifacts/certificate-generator/Dockerfile @@ -0,0 +1,20 @@ +FROM golang:1.14.1-alpine3.11 as builder + +WORKDIR /workdir +COPY . /workdir + +RUN set -x && \ + apk --no-cache add git gcc libc-dev make + +RUN git clone https://github.com/cloudflare/cfssl.git && \ + cd cfssl && make + +FROM alpine:3.11 +COPY --from=builder /workdir/cfssl /etc/cfssl +COPY --from=builder /workdir/cfssl/bin/ /usr/bin + +RUN mkdir -p /src +COPY . /src +WORKDIR /src + +ENTRYPOINT [ "/src/generate-certs-script" ] diff --git a/artifacts/certificate-generator/configuration/cfssl.conf b/artifacts/certificate-generator/configuration/cfssl.conf new file mode 100644 index 00000000..ea8f4863 --- /dev/null +++ b/artifacts/certificate-generator/configuration/cfssl.conf @@ -0,0 +1,54 @@ +{ + "signing": { + "default": { + "expiry": "8760h" + }, + "profiles": { + "intermediate_ca": { + "usages": [ + "signing", + "digital signature", + "key encipherment", + "cert sign", + "crl sign", + "server auth", + "client auth" + ], + "expiry": "43600h", + "ca_constraint": { + "is_ca": true, + "max_path_len": 0, + "max_path_len_zero": true + } + }, + "peer": { + "usages": [ + "signing", + "digital signature", + "key encipherment", + "client auth", + "server auth" + ], + "expiry": "8760h" + }, + "server": { + "usages": [ + "signing", + "digital signing", + "key encipherment", + "server auth" + ], + "expiry": "8760h" + }, + "client": { + "usages": [ + "signing", + "digital signature", + "key encipherment", + "client auth" + ], + "expiry": "8760h" + } + } + } +} diff --git a/artifacts/certificate-generator/configuration/dap-follower.json b/artifacts/certificate-generator/configuration/dap-follower.json new file mode 100644 index 00000000..adaa6f81 --- /dev/null +++ b/artifacts/certificate-generator/configuration/dap-follower.json @@ -0,0 +1,19 @@ +{ + "CN": "conjur-follower.mycompany.local", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "L": "Newton", + "ST": "Massachusetts", + "O": "Dynamic Access Provider", + "OU": "Follower" + } + ], + "hosts": [ + "conjur-follower-1.mycompany.local" + ] +} diff --git a/artifacts/certificate-generator/configuration/dap-master.json b/artifacts/certificate-generator/configuration/dap-master.json new file mode 100644 index 00000000..b7d9be41 --- /dev/null +++ b/artifacts/certificate-generator/configuration/dap-master.json @@ -0,0 +1,22 @@ +{ + "CN": "conjur-master.mycompany.local", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "L": "Newton", + "ST": "Massachusetts", + "O": "Dynamic Access Provider", + "OU": "Master" + } + ], + "hosts": [ + "conjur-master.mycompany.local", + "conjur-master-1.mycompany.local", + "conjur-master-2.mycompany.local", + "conjur-master-3.mycompany.local" + ] +} diff --git a/artifacts/certificate-generator/configuration/intermediate-1/intermediate-csr.json b/artifacts/certificate-generator/configuration/intermediate-1/intermediate-csr.json new file mode 100644 index 00000000..1b3bda74 --- /dev/null +++ b/artifacts/certificate-generator/configuration/intermediate-1/intermediate-csr.json @@ -0,0 +1,19 @@ +{ + "CN": "Cyberark USA Engineering Intermediate 1 CA", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "ST": "Massachusetts", + "L": "Newton", + "O": "Cyberark USA Engineering", + "OU": "Conjur" + } + ], + "ca": { + "expiry": "42720h" + } +} diff --git a/artifacts/certificate-generator/configuration/intermediate-1/root_to_intermediate_ca.json b/artifacts/certificate-generator/configuration/intermediate-1/root_to_intermediate_ca.json new file mode 100644 index 00000000..6e118c20 --- /dev/null +++ b/artifacts/certificate-generator/configuration/intermediate-1/root_to_intermediate_ca.json @@ -0,0 +1,18 @@ +{ + "signing": { + "default": { + "usages": [ + "digital signature", + "cert sign", + "crl sign", + "signing" + ], + "expiry": "87600h", + "ca_constraint": { + "is_ca": true, + "max_path_len":0, + "max_path_len_zero": true + } + } + } +} diff --git a/artifacts/certificate-generator/configuration/intermediate-2/intermediate-csr.json b/artifacts/certificate-generator/configuration/intermediate-2/intermediate-csr.json new file mode 100644 index 00000000..6b060a90 --- /dev/null +++ b/artifacts/certificate-generator/configuration/intermediate-2/intermediate-csr.json @@ -0,0 +1,19 @@ +{ + "CN": "Cyberark USA Engineering Intermediate 2 CA", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "ST": "Massachusetts", + "L": "Newton", + "O": "Cyberark USA Engineering", + "OU": "Conjur" + } + ], + "ca": { + "expiry": "42720h" + } +} diff --git a/artifacts/certificate-generator/configuration/intermediate_ca.json b/artifacts/certificate-generator/configuration/intermediate_ca.json new file mode 100644 index 00000000..a7ca70ee --- /dev/null +++ b/artifacts/certificate-generator/configuration/intermediate_ca.json @@ -0,0 +1,19 @@ +{ + "CN": "Cyberark Conjur", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "ST": "Massachusetts", + "L": "Newton", + "O": "Cyberark USA Engineering", + "OU": "Conjur" + } + ], + "ca": { + "expiry": "42720h" + } +} diff --git a/artifacts/certificate-generator/configuration/root_ca.json b/artifacts/certificate-generator/configuration/root_ca.json new file mode 100644 index 00000000..1925d955 --- /dev/null +++ b/artifacts/certificate-generator/configuration/root_ca.json @@ -0,0 +1,16 @@ +{ + "CN": "Cyberark Conjur Root CA", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "ST": "Massachusetts", + "L": "Newton", + "O": "Cyberark USA Engineering", + "OU": "Conjur" + } + ] +} diff --git a/artifacts/certificate-generator/generate-certs-script b/artifacts/certificate-generator/generate-certs-script new file mode 100755 index 00000000..0e884bee --- /dev/null +++ b/artifacts/certificate-generator/generate-certs-script @@ -0,0 +1,147 @@ +#!/bin/ash -e +set -o pipefail + +config_path="/src/configuration" +certificate_path="/src/certificates" + +# Generated Cert paths +root_destination="$certificate_path/root_ca/ca" +intermediate_destination="$certificate_path/intermediate_ca/intermediate" +master_destination="$certificate_path/dap_master/dap-master" +follower_destination="$certificate_path/dap_follower/dap-follower" + +GENERATE_CA=true +GENERATE_SERVER=true +FORCE=false + +main() { + echo "$@" + while true ; do + case "$1" in + --rotate-server ) GENERATE_CA=false; shift ;; + --force ) FORCE=true; shift ;; + -h | --help ) print_help ; shift ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac + done + + create_folders + generate_certificates +} + +print_help() { + cat << EOF + +Generates a Root, Intermediate, DAP Master and Follower certificates + +Usage: bin/generate-certs [options] + + -h, --help Shows this help message. + --rotate-server Only generate new server certificates + --force Generate certificates even if they already exist + +EOF + exit +} + +create_folders() { + folders='root_ca intermediate_ca dap_master dap_follower' + for folder in $folders ; do + mkdir -p "$certificate_path/$folder" + done +} + +generate_certificates() { + if [ "$GENERATE_CA" = true ]; then + # Generate Root Certificate if it does not exist + if [ ! -f "$root_destination.pem" ] || [ "$FORCE" = true ]; then + cfssl gencert -initca "$config_path/root_ca.json" | \ + cfssljson -bare $root_destination + fi + + # Generate and sign intermediate certificate if it does not exist + if [ ! -f "$intermediate_destination.pem" ] || [ "$FORCE" = true ]; then + # Generate Intermediate Certificate + cfssl gencert -initca $config_path/intermediate_ca.json | \ + cfssljson -bare $intermediate_destination + + # Sign Intermediate with Root + cfssl sign \ + -ca $root_destination.pem \ + -ca-key $root_destination-key.pem \ + -config $config_path/cfssl.conf \ + -profile intermediate_ca \ + $intermediate_destination.csr | cfssljson -bare $intermediate_destination + fi + + cat $certificate_path/intermediate_ca/intermediate.pem \ + $certificate_path/root_ca/ca.pem > \ + $certificate_path/ca-chain.pem + fi + + # Generate and sign master certificate w/ intermediate + if [ "$GENERATE_SERVER" = true ]; then + if [ ! -f "$master_destination-key.pem" ]; then + generate_master_key + fi + + if [ ! -f "$master_destination.pem" ] || [ "$FORCE" = true ]; then + generate_master_csr + issue_master_certificate + fi + + if [ ! -f "$follower_destination-key.pem" ]; then + generate_follower_key + fi + + # Generate and sign follower certificate w/ intermediate + if [ ! -f "$follower_destination.pem" ] || [ "$FORCE" = true ]; then + generate_follower_csr + issue_follower_certificate + fi + fi +} + +generate_master_key() { + cfssl genkey \ + -config $config_path/cfssl.conf \ + $config_path/dap-master.json | cfssljson -bare $master_destination +} + +generate_master_csr() { + cfssl gencsr \ + -key "$master_destination-key.pem" \ + $config_path/dap-master.json | cfssljson -bare $master_destination +} + +issue_master_certificate() { + cfssl sign \ + -ca $intermediate_destination.pem \ + -ca-key $intermediate_destination-key.pem \ + -config $config_path/cfssl.conf \ + -profile=peer \ + $master_destination.csr | cfssljson -bare $master_destination +} + +generate_follower_key() { + cfssl genkey \ + -config $config_path/cfssl.conf \ + $config_path/dap-follower.json | cfssljson -bare $follower_destination +} + +generate_follower_csr() { + cfssl gencsr \ + -key "$follower_destination-key.pem" \ + $config_path/dap-follower.json | cfssljson -bare $follower_destination +} + +issue_follower_certificate() { + cfssl sign \ + -ca $intermediate_destination.pem \ + -ca-key $intermediate_destination-key.pem \ + -config $config_path/cfssl.conf \ + -profile=peer \ + $follower_destination.csr | cfssljson -bare $follower_destination +} + +main "$@" diff --git a/bin/api b/bin/api new file mode 100755 index 00000000..12e7d0ad --- /dev/null +++ b/bin/api @@ -0,0 +1,4 @@ +#!/bin/bash -e + +export VERSION='5.0-stable' +docker-compose run --no-deps --rm api-client bin/api "$@" \ No newline at end of file diff --git a/bin/cli b/bin/cli new file mode 100755 index 00000000..523edc46 --- /dev/null +++ b/bin/cli @@ -0,0 +1,15 @@ +#!/bin/bash -e + +function proxy_command { + cmd="$@" + docker-compose run --rm -w /src/cli --entrypoint /bin/bash client -c " + if [ ! -e /root/conjur-demo.pem ]; then + yes 'yes' | conjur init -u https://conjur-master.mycompany.local -a demo + fi + conjur authn login -u admin -p MySecretP@ss1 + hostname -I + eval exec \"$cmd\" + " +} + +proxy_command "$@" diff --git a/bin/dap b/bin/dap new file mode 100755 index 00000000..7e40e2a2 --- /dev/null +++ b/bin/dap @@ -0,0 +1,622 @@ +#!/usr/bin/env bash + +set -e + +_admin_password="MySecretP@ss1" + +function _print_help { + cat << EOF + +A tool that provides a variety of DAP lifecycle workflows. + +Synopsis: bin/dap [command options] + +Usage: bin/dap [options]: + + --create-backup Creates a backup|Requires configured master + --dry-run Print configuration commands with executing + --enable-auto-failover Configures Master cluster with auto-failover (Requires configured master and standbys) + --generate-dh Don't mount pre-generated DH params into the appliance containers (will cause a _lot_ more CPU consumption) + --h, --help Shows this help message + --import-custom-certificates Imports pre-generated 3rd-party certificates (Requires configured master) + --promote-standby Stops the current master and promotes a standby (Requires configured standbys and no auto-failover) + --provision-follower Configures follower behind a Layer 7 load balancer (Requires configured master) + --provision-master Configures a DAP Master with account `demo` and password `MySecretP@ss1` behind a Layer 4 load balancer + --provision-standbys Deploys and configures two standbys (Requires configured master) + --restore-from-backup Restores a master from backup|Requires a previously created backup + --stop Stops all containers and cleans up cached files + --trigger-failover Stops current master (Requires an auto-failover cluster) + --trust-follower-proxy Adds Follower load balancer as a trusted proxy (Requires a configured follower) + --upgrade-master Restores master from backup (Requires configured master) + --wait-for-master Blocks until the Master is healthy + --version Version of DAP to use (defaults to latest build) + --standby-count Number of Standbys to deploy (defaults to 2) + + +EOF + exit +} + +function _set_master_multi_node_proxy_config { + cat << EOF > files/haproxy/master/haproxy.cfg +global + daemon + maxconn 256 + log-send-hostname + +defaults + mode tcp + option http-use-htx + timeout connect 5000ms + timeout client 50000ms + timeout server 50000ms + +# +# Peform SSL Pass-Through to proxy HTTPS requests to DAP +# +frontend www + mode tcp + bind *:443 + option tcplog + default_backend www-backend + +# +# Peform SSL pass-through to proxy Postgres TCP requests from standbys/followers to DAP Master +# +frontend postgres + mode tcp + bind *:5432 + option tcplog + default_backend postgres-backend + +# +# Peform SSL pass-through to proxy Syslog TCP requests from followers to DAP Master +# +frontend syslog + mode tcp + bind *:1999 + option tcplog + default_backend syslog-backend + +# +# Performs Layer 4 proxy +# Uses DAP's HTTP health endpoint to determine master +# +backend www-backend + mode tcp + balance roundrobin + option httpchk GET /health + server conjur-master-1 conjur-master-1.mycompany.local:443 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem +$(_standby_backend_www_lines) + +# +# Performs Layer 4 proxy +# Uses DAP's HTTP health endpoint to determine master +# +backend postgres-backend + mode tcp + balance roundrobin + option httpchk GET /health + server conjur-master-1 conjur-master-1.mycompany.local:5432 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem +$(_standby_backend_postgres_lines) + +# +# Performs Layer 4 proxy +# Uses DAP's HTTP health endpoint to determine master +# +backend syslog-backend + mode tcp + balance roundrobin + option httpchk GET /health + server conjur-master-1 conjur-master-1.mycompany.local:1999 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem +$(_standby_backend_syslog_lines) + +# +# Enables HAProxy's UI for debugging +# +listen stats + mode http + bind *:7000 + stats enable + stats uri / +EOF +} + +_standby_backend_www_lines() { + declare -a standby_servers + + # The identifier for the Leader is 1, so we start at 2 for Standbys + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + standby_servers+=(" server conjur-master-$i conjur-master-$i.mycompany.local:443 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem") + done + + printf '%s' "$(IFS=$'\n' ; echo "${standby_servers[*]}")" +} + +_standby_backend_postgres_lines() { + declare -a standby_servers + + # The identifier for the Leader is 1, so we start at 2 for Standbys + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + standby_servers+=(" server conjur-master-$i conjur-master-$i.mycompany.local:5432 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem") + done + + printf '%s' "$(IFS=$'\n' ; echo "${standby_servers[*]}")" +} + +_standby_backend_syslog_lines() { + declare -a standby_servers + + # The identifier for the Leader is 1, so we start at 2 for Standbys + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + standby_servers+=(" server conjur-master-$i conjur-master-$i.mycompany.local:1999 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem") + done + + printf '%s' "$(IFS=$'\n' ; echo "${standby_servers[*]}")" +} + +function _set_master_single_node_proxy_config { + cp files/haproxy/master/single/haproxy.cfg files/haproxy/master/haproxy.cfg +} + +function _run { + local _all_args=("$@") + local _node_name=$1 + local _args=("${_all_args[@]:1}") + + echo "Running Command (on $_node_name): docker exec cyberark-dap $_args" + + if [[ $DRY_RUN = false ]]; then + docker-compose exec -T $_node_name bash -c " + $_args + " + fi +} + +function _start_master { + if [[ $DRY_RUN = false ]]; then + + if [[ "$PULL_IMAGES" = "true" ]]; then + docker-compose pull + fi + + _set_master_single_node_proxy_config + docker-compose up -d --no-deps conjur-master.mycompany.local \ + conjur-master-1.mycompany.local + fi +} + +function _start_l7_load_balancer { + if [[ $DRY_RUN = false ]]; then + docker-compose up -d --no-deps conjur-follower.mycompany.local + fi +} + +function _configure_master { + _cmd="evoke configure master" + _cmd="$_cmd --accept-eula" + _cmd="$_cmd --hostname conjur-master.mycompany.local" + _cmd="$_cmd --master-altnames conjur-master-1.mycompany.local,$(_standby_altnames)" + _cmd="$_cmd --admin-password $_admin_password" + _cmd="$_cmd demo" + + _run conjur-master-1.mycompany.local \ + "$_cmd" +} + +function _setup_standby { + local _standby_number=$1 + + docker-compose rm --stop --force "conjur-master-$_standby_number.mycompany.local" + docker-compose up --no-deps --detach "conjur-master-$_standby_number.mycompany.local" + + # Generate a Seed File + _run conjur-master-1.mycompany.local \ + "evoke seed standby conjur-master-$_standby_number.mycompany.local conjur-master-1.mycompany.local > /opt/cyberark/dap/seeds/standby-seed-$_standby_number.tar" + + # Unpack and Configure + _run conjur-master-$_standby_number.mycompany.local \ + "evoke unpack seed /opt/cyberark/dap/seeds/standby-seed-$_standby_number.tar && evoke configure standby" +} + +function _start_standby_synchronization { + _run conjur-master-1.mycompany.local \ + "evoke replication sync start" +} + +function _setup_follower { + + docker-compose rm --stop --force conjur-follower-1.mycompany.local + docker-compose up --no-deps --detach conjur-follower-1.mycompany.local + + # Generate Seed file + _run conjur-master-1.mycompany.local \ + "evoke seed follower conjur-follower.mycompany.local > /opt/cyberark/dap/seeds/follower-seed.tar" + + # Unpack and Configure + _run conjur-follower-1.mycompany.local \ + "evoke unpack seed /opt/cyberark/dap/seeds/follower-seed.tar && evoke configure follower" + + _start_l7_load_balancer +} + +# +## Failover & Promotion +# +function _perform_promotion { + # Stop current master + if [[ $DRY_RUN = false ]]; then + docker-compose stop conjur-master-1.mycompany.local + fi + + # Promote Standby to Master + _run conjur-master-2.mycompany.local \ + "evoke role promote" + + # Repoint Standby to updated Master + _run conjur-master-3.mycompany.local \ + "evoke replication rebase conjur-master-2.mycompany.local" +} + +function _single_master { + _start_master + _configure_master + echo "DAP instance available at: 'https://localhost'" + echo "Login using with the username/password: 'admin'/'$_admin_password'" +} + +function _reload_container { + name="$1" + docker-compose rm --stop --force $name + docker-compose up --no-deps --detach $name + +} + +function _setup_standbys { + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + _setup_standby "$i" + done + _start_standby_synchronization + + # Reload load balancer to serve cluster + _set_master_multi_node_proxy_config + _reload_container 'conjur-master.mycompany.local' +} + +function _command { + docker run --rm -w /dap-intro -v "$(pwd):/dap-intro" alpine "$@" +} + +function _stop { + echo "stopping...." + docker-compose down -v + docker network remove dap_net || true + + _command rm -rf cli_cache + _command rm -rf system/backup + _command rm -rf system/logs + _command rm files/haproxy/master/haproxy.cfg || true + echo "stopped" + exit +} + +function _cli { + local _namespace=$1 + local _policy=$2 + + echo "Loading Policy '$_policy':" + cat $_policy + echo '' + echo "with command: 'conjur policy load $_namespace $_policy'" + echo '' + echo '' + + if [[ $DRY_RUN = false ]]; then + bin/cli conjur policy load $_namespace $_policy + fi +} + +function _disable_autofailover { + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + _run "conjur-master-$i.mycompany.local" "evoke cluster member remove conjur-master-$i.mycompany.local" + done +} + +function _enable_autofailover { + autofailover=$(curl -k https://localhost/info | jq -r .configuration.conjur.cluster_name) + + if [ "$autofailover" = 'production' ]; then + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + _run "conjur-master-$i.mycompany.local" "evoke cluster enroll --reenroll --cluster-machine-name conjur-master-$i.mycompany.local --master-name conjur-master-1.mycompany.local production" + done + else + _cli root "policy/base.yml" + + _set_cluster_policy_file + _cli conjur/cluster policy/cluster.yml + + _run conjur-master-1.mycompany.local "evoke cluster enroll --cluster-machine-name conjur-master-1.mycompany.local production" + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + _run "conjur-master-$i.mycompany.local" "evoke cluster enroll --cluster-machine-name conjur-master-$i.mycompany.local --master-name conjur-master-1.mycompany.local production" + done + fi +} + +_set_cluster_policy_file() { + cat << EOF > policy/cluster.yml +- !policy + id: production + body: + - !layer + + # Host nodes to be enrolled in the `production` auto-failover cluster + - &hosts + - !host conjur-master-1.mycompany.local +$(_standby_host_lines) + + - !grant + role: !layer + member: *hosts +EOF +} + +_standby_host_lines() { + declare -a standby_servers + + # The identifier for the Leader is 1, so we start at 2 for Standbys + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + standby_servers+=(" - !host conjur-master-$i.mycompany.local") + done + + printf '%s' "$(IFS=$'\n' ; echo "${standby_servers[*]}")" +} + +function _stop_replication { + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + if [[ $(docker ps --quiet --filter "name=conjur-master-$i.mycompany.local") ]]; then + _run "conjur-master-$i.mycompany.local" "evoke replication stop" + fi + done +} + +function _stop_and_rename { + local container_name="$1" + local rename_to="$2" + docker-compose stop $container_name + image_id=$(docker ps --all --quiet --filter "name=$container_name") + docker rename $image_id $rename_to +} + +function _upgrade_via_backup_restore { + upgrade_to="$1" + + autofailover=$(curl -k https://localhost/info | jq -r .configuration.conjur.cluster_name) + + if [ "$autofailover" = 'production' ]; then + _disable_autofailover + fi + _upgrade_master_via_backup_restore $upgrade_to +} + +function _stop_and_remove_master { + docker-compose rm --stop --force conjur-master-1.mycompany.local +} + +function _restore_from_backup { + _stop_and_remove_master + _start_master + + # Unpack the backup with docker exec evoke unpack backup -k /opt/conjur/backup/key /opt/conjur/backup/ + _run conjur-master-1.mycompany.local 'evoke unpack backup --key /opt/conjur/backup/key /opt/conjur/backup/$(ls -1t /opt/conjur/backup | grep gpg | head -1)' + + # Configure the new master with docker exec evoke restore master + _run conjur-master-1.mycompany.local "evoke restore --accept-eula" +} + +function _upgrade_master_via_backup_restore { + upgrade_to="$1" + # Run evoke replication stop on existing standbys and followers + _stop_replication + + # Generate a backup on the existing master using evoke backup + _create_backup + + # Stop the existing master container with docker stop and rename + _stop_and_rename 'conjur-master-1.mycompany.local' 'conjur-master-1.mycompany.local_backup' + + # Start a container using the new version image (this will become the new master) + export VERSION=$upgrade_to + _restore_from_backup + + # Confirm master is healthy + # ... +} + +function _create_backup { + _run conjur-master-1.mycompany.local \ + "evoke backup" +} + +function _add_follower_proxy { + _run conjur-follower-1.mycompany.local \ + "evoke proxy add 12.16.23.15" +} + +function _trigger_master_failover_failover { + _run conjur-master-1.mycompany.local \ + "sv stop conjur" + echo 'Auto-failover takes about a minute to complete.' +} + +function _import_certificates { + bin/generate-certs + + local cert_path='/opt/cyberark/dap/configuration/certificates' + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --root $cert_path/ca-chain.pem" + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_master/dap-master-key.pem --set $cert_path/dap_master/dap-master.pem" + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem $cert_path/dap_follower/dap-follower.pem" +} + +function _rotate_certificates { + bin/generate-certs --rotate-server --force + + # Disable auto-failover while rotating the Master cluster certificates + # to prevent an unintended failover. + _pause_autofailover + + # Import the new certificate into the active DAP Master + local cert_path='/opt/cyberark/dap/configuration/certificates' + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_master/dap-master-key.pem --set $cert_path/dap_master/dap-master.pem" + + # Import the new Follower certificate into the active DAP master so that it + # is available through the seed service + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem $cert_path/dap_follower/dap-follower.pem" + + # Import the new certificate into the DAP Standbys + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + if [[ $(docker ps --quiet --filter "name=conjur-master-$i.mycompany.local") ]]; then + _run "conjur-master-$i.mycompany.local" \ + "evoke ca import --force --key $cert_path/dap_master/dap-master-key.pem --set $cert_path/dap_master/dap-master.pem" + + # Import the new Follower certificate into each DAP Standby so that it + # is available through the seed service if the Standby is promoted. + _run "conjur-master-$i.mycompany.local" \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem $cert_path/dap_follower/dap-follower.pem" + fi + done + + # Re-enable auto-failover for the Master cluster + _resume_autofailover + + if [[ $(docker ps --quiet --filter "name=conjur-follower-1.mycompany.local") ]]; then + # Import the new certificate into each Follower + _run conjur-follower-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem --set $cert_path/dap_follower/dap-follower.pem" + fi +} + +function _pause_autofailover { + autofailover=$(curl -k https://localhost/info | jq -r .configuration.conjur.cluster_name) + if [ "$autofailover" = 'production' ]; then + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + _run "conjur-master-$i.mycompany.local" "sv down cluster" + done + fi +} + +function _resume_autofailover { + autofailover=$(curl -k https://localhost/info | jq -r .configuration.conjur.cluster_name) + if [ "$autofailover" = 'production' ]; then + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + _run conjur-master-3.mycompany.local "sv up cluster" + done + fi +} + +function _wait_for_master { + local master_url="https://localhost" + + echo "Waiting for DAP Master to be ready..." + + # Wait for 10 successful connections in a row + local COUNTER=0 + while [ $COUNTER -lt 10 ]; do + local response + response=$(curl -k --silent --head "$master_url/health" || true) + + if ! echo "$response" | grep -q "Conjur-Health: OK"; then + sleep 5 + COUNTER=0 + else + (( COUNTER=COUNTER+1 )) + fi + + sleep 1 + echo "Successful Health Checks: $COUNTER" + done +} + +_standby_altnames() { + + declare -a standby_altnames + + # The identifier for the Leader is 1, so we start at 2 for Standbys + for ((i=2; i<=STANDBY_COUNT+1; i++)) + do + standby_altnames+=("conjur-master-$i.mycompany.local") + done + + # Output the command delimited string + echo "$(IFS=, ; echo "${standby_altnames[*]}")" +} + +create_docker_network() { + + # Cleanup any old, unused networks, including the previous DAP Docker Compose + # networks. + docker network prune --force + + dap_net_pid=$(docker network ls --quiet --filter name=dap_net) + if [[ -z "$dap_net_pid" ]]; then + docker network create \ + --driver bridge \ + --ipam-driver default \ + --subnet 12.16.23.0/27 \ + dap_net + fi +} + +TAG=5.0-stable +DRY_RUN=false +PULL_IMAGES=false +CMD="" +export DHPATH="${DHPATH:-/etc/ssl}" +STANDBY_COUNT=2 + +while true ; do + case "$1" in + --provision-master ) CMD='_single_master' ; shift ;; + --promote-standby ) CMD='_perform_promotion' ; shift ;; + --import-custom-certificates ) CMD='_import_certificates' ; shift ;; + --rotate-custom-certificates ) CMD='_rotate_certificates' ; shift ;; + --provision-standbys ) CMD='_setup_standbys' ; shift ;; + --enable-auto-failover ) CMD='_enable_autofailover' ; shift ;; + --provision-follower ) CMD='_setup_follower' ; shift ;; + --upgrade-master ) shift ; CMD="_upgrade_via_backup_restore $1" ; shift ;; + --version ) shift ; TAG=$1 ; shift ;; + --standby-count ) shift; STANDBY_COUNT=$1 ; shift ;; + --dry-run ) DRY_RUN=true ; shift ;; + -h | --help ) _print_help ; shift ;; + --trigger-failover ) CMD='_trigger_master_failover_failover' ; shift ;; + --create-backup ) CMD='_create_backup' ; shift ;; + --restore-from-backup ) CMD='_restore_from_backup' ; shift ;; + --trust-follower-proxy ) CMD='_add_follower_proxy' ; shift ;; + --wait-for-master ) CMD='_wait_for_master' ; shift ;; + --generate-dh ) export DHPATH=/tmp ; shift ;; + --stop ) _stop ; shift ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac +done + +export VERSION=$TAG + +create_docker_network + +eval $CMD diff --git a/bin/generate-certs b/bin/generate-certs new file mode 100755 index 00000000..4f2a31e6 --- /dev/null +++ b/bin/generate-certs @@ -0,0 +1,5 @@ +#!/bin/bash -e + +export VERSION='5.0-stable' + +docker-compose run --no-deps --rm certificate-generator "$@" diff --git a/bin/install b/bin/install new file mode 100755 index 00000000..546af6c4 --- /dev/null +++ b/bin/install @@ -0,0 +1,15 @@ +#!/bin/bash -e + +container=$(docker ps -aqf "name=master-1.mycompany.local") +if [ "$1" != "" ]; then + while [ "$1" != "" ]; do + filename=$(basename "$1") + + docker cp $1 $container:/tmp/$filename + docker exec $container dpkg -i /tmp/$filename + + shift + done + docker exec $container sv stop conjur + docker exec $container sv start conjur +fi diff --git a/bin/podman-api b/bin/podman-api new file mode 100755 index 00000000..f154d9b4 --- /dev/null +++ b/bin/podman-api @@ -0,0 +1,21 @@ +#!/bin/bash -e + +export VERSION='5.0-stable' + +function proxy_command { + cmd="$@" + echo "$@" + podman build -t docker.io/api-client -f ./artifacts/api-client + podman run --name api-client \ + --rm --privileged --restart=no \ + --network dap_net \ + --volume .:/src:Z \ + --volume ./artifacts/api-client/api-script:/src/bin/api:Z \ + --volume ./policy:/src/policy:Z \ + -w /src \ + --entrypoint /src/bin/api \ + docker.io/api-client \ + "$cmd" +} + +proxy_command "$@" \ No newline at end of file diff --git a/bin/podman-cli b/bin/podman-cli new file mode 100755 index 00000000..140c38d9 --- /dev/null +++ b/bin/podman-cli @@ -0,0 +1,29 @@ +#!/bin/bash -e + +function proxy_command { + cmd="$@" + + mkdir -p ./cli_cache/master + + podman run --name client \ + --rm --privileged --restart=no \ + --network dap_net \ + --volume .:/src/cli:Z \ + --volume ./cli_cache/master:/root:Z \ + -e CONJUR_APPLIANCE_URL=https://conjur-master.mycompany.local \ + -e CONJUR_ACCOUNT=demo \ + -e CONJUR_AUTHN_LOGIN=admin \ + -w /src/cli \ + --entrypoint /bin/bash \ + cyberark/conjur-cli:5 \ + -c " + if [ ! -e /root/conjur-demo.pem ]; then + yes 'yes' | conjur init -u https://conjur-master.mycompany.local -a demo + fi + conjur authn login -u admin -p MySecretP@ss1 + hostname -I + eval exec \"$cmd\" + " +} + +proxy_command "$@" diff --git a/bin/podman-dap b/bin/podman-dap new file mode 100755 index 00000000..97160983 --- /dev/null +++ b/bin/podman-dap @@ -0,0 +1,547 @@ +#!/bin/bash -e +_admin_password="MySecretP@ss1" + +function _print_help { + cat << EOF + +A tool that provides a variety of DAP lifecycle workflows. + +Synopsis: bin/dap [command options] + +Usage: bin/dap [options]: + + --create-backup Creates a backup|Requires configured master + --dry-run Print configuration commands with executing + --enable-auto-failover Configures Master cluster with auto-failover (Requires configured master and standbys) + --generate-dh Don't mount pre-generated DH params into the appliance containers (will cause a _lot_ more CPU consumption) + --h, --help Shows this help message + --import-custom-certificates Imports pre-generated 3rd-party certificates (Requires configured master) + --promote-standby Stops the current master and promotes a standby (Requires configured standbys and no auto-failover) + --provision-follower Configures follower behind a Layer 7 load balancer (Requires configured master) + --provision-master Configures a DAP Master with account `demo` and password `MySecretP@ss1` behind a Layer 4 load balancer + --provision-standbys Deploys and configures two standbys (Requires configured master) + --restore-from-backup Restores a master from backup|Requires a previously created backup + --stop Stops all containers and cleans up cached files + --trigger-failover Stops current master (Requires an auto-failover cluster) + --trust-follower-proxy Adds Follower load balancer as a trusted proxy (Requires a configured follower) + --upgrade-master Restores master from backup (Requires configured master) + --wait-for-master Blocks until the Master is healthy + --version Version of DAP to use (defaults to latest build) + + +EOF + exit +} + +function _set_master_multi_node_proxy_config { + cp files/haproxy/master/multi-node/haproxy.cfg files/haproxy/master/haproxy.cfg +} + +function _set_master_single_node_proxy_config { + cp files/haproxy/master/single/haproxy.cfg files/haproxy/master/haproxy.cfg +} + +function _run { + local _all_args=("$@") + local _node_name=$1 + local _args=("${_all_args[@]:1}") + + echo "Running Command (on $_node_name): podman exec cyberark-dap $_args" + + if [[ $DRY_RUN = false ]]; then + podman exec $_node_name bash -c " + $_args + " + fi +} + +function _start_master { + if [[ $DRY_RUN = false ]]; then + + if [[ "$PULL_IMAGES" = "true" ]]; then + podman pull haproxy:2.1-alpine + podman pull registry.tld/conjur-appliance:$VERSION + fi + + _set_master_single_node_proxy_config + + podman run --name conjur-master.mycompany.local \ + -d --privileged --restart=unless-stopped \ + --security-opt seccomp=unconfined \ + --publish "10443:443" \ + --publish "7000:7000" \ + --log-driver journald \ + --network dap_net \ + --volume master-certs:/etc/ssl/certs:Z \ + --volume ./files/haproxy/master:/usr/local/etc/haproxy:Z \ + haproxy:2.1-alpine + + mkdir -p ./system/backup + mkdir -p ./system/logs/master-1 + + podman run --name conjur-master-1.mycompany.local \ + -d --privileged --restart=unless-stopped \ + --security-opt seccomp=unconfined \ + --publish "10444:443" \ + --publish "5432:5432" \ + --publish "1999:1999" \ + --log-driver journald \ + --network dap_net \ + --volume seeds:/opt/cyberark/dap/seeds \ + --volume master-certs:/opt/conjur/etc/ssl \ + --volume ./system/backup:/opt/conjur/backup:Z \ + --volume ./system/configuration:/opt/cyberark/dap/configuration:Z \ + --volume ./system/logs/master-1:/var/log/conjur:Z \ + --volume ./files:/conjur_files \ + --volume ./files/dhparam.pem:${DHPATH}/dhparam.pem \ + --volume ./files/cluster.conf:/opt/conjur/etc/cluster.conf \ + --volume ./files/etcd.conf:/etc/etcd/etcd.conf \ + registry.tld/conjur-appliance:$VERSION + fi +} + +function _start_l7_load_balancer { + if [[ $DRY_RUN = false ]]; then + podman run --name conjur-follower.mycompany.local \ + -d --privileged --restart=unless-stopped \ + --security-opt seccomp=unconfined \ + --publish "10450:443" \ + --publish "7001:7000" \ + --log-driver journald \ + --network dap_net \ + --volume follower-certs:/etc/ssl/certs:Z \ + --volume ./files/haproxy/follower:/usr/local/etc/haproxy:Z \ + haproxy:2.1-alpine + fi +} + +function _configure_master { + _cmd="evoke configure master" + _cmd="$_cmd --accept-eula" + _cmd="$_cmd --hostname conjur-master.mycompany.local" + _cmd="$_cmd --master-altnames conjur-master-1.mycompany.local,conjur-master-2.mycompany.local,conjur-master-3.mycompany.local,conjur-master-4.mycompany.local,conjur-master-5.mycompany.local" + _cmd="$_cmd --admin-password $_admin_password" + _cmd="$_cmd demo" + + _run conjur-master-1.mycompany.local \ + "$_cmd" +} + +function _setup_standby { + local _standby_number=$1 + + mkdir -p ./system/logs/master-$_standby_number + + podman run --name conjur-master-$_standby_number.mycompany.local \ + -d --privileged --restart=unless-stopped \ + --security-opt seccomp=unconfined \ + --publish "$((10443 + $1)):443" \ + --publish "$((5432 + $1)):5432" \ + --publish "$((1999 + $1)):1999" \ + --log-driver journald \ + --network dap_net \ + --volume seeds:/opt/cyberark/dap/seeds \ + --volume master-certs:/opt/conjur/etc/ssl \ + --volume ./system/backup:/opt/conjur/backup:Z \ + --volume ./system/configuration:/opt/cyberark/dap/configuration:Z \ + --volume ./system/logs/master-$_standby_number:/var/log/conjur:Z \ + --volume ./files:/conjur_files \ + --volume ./files/cluster.conf:/opt/conjur/etc/cluster.conf \ + --volume ./files/etcd.conf:/etc/etcd/etcd.conf \ + registry.tld/conjur-appliance:$VERSION + + # Generate a Seed File + _run conjur-master-1.mycompany.local \ + "evoke seed standby conjur-master-$_standby_number.mycompany.local conjur-master-1.mycompany.local > /opt/cyberark/dap/seeds/standby-seed-$_standby_number.tar" + + # Unpack and Configure + _run conjur-master-$_standby_number.mycompany.local \ + "evoke unpack seed /opt/cyberark/dap/seeds/standby-seed-$_standby_number.tar && evoke configure standby" +} + +function _start_standby_synchronization { + _run conjur-master-1.mycompany.local \ + "evoke replication sync start" +} + +function _setup_follower { + + mkdir -p ./system/logs/follower-1 + + podman run --name conjur-follower-1.mycompany.local\ + -d --privileged --restart=unless-stopped \ + --security-opt seccomp=unconfined \ + --publish "10449:443" \ + --publish "5440:5432" \ + --publish "2010:1999" \ + --log-driver journald \ + --network dap_net \ + --volume seeds:/opt/cyberark/dap/seeds \ + --volume follower-certs:/opt/conjur/etc/ssl \ + --volume ./system/backup:/opt/conjur/backup:Z \ + --volume ./system/configuration:/opt/cyberark/dap/configuration:Z \ + --volume ./system/logs/follower-1:/var/log/conjur:Z \ + --volume ./files:/conjur_files \ + --volume ./files/cluster.conf:/opt/conjur/etc/cluster.conf \ + --volume ./files/etcd.conf:/etc/etcd/etcd.conf \ + registry.tld/conjur-appliance:$VERSION + + # Generate Seed file + _run conjur-master-1.mycompany.local \ + "evoke seed follower conjur-follower.mycompany.local > /opt/cyberark/dap/seeds/follower-seed.tar" + + # Unpack and Configure + _run conjur-follower-1.mycompany.local \ + "evoke unpack seed /opt/cyberark/dap/seeds/follower-seed.tar && evoke configure follower" + + _start_l7_load_balancer +} + +# +## Failover & Promotion +# +function _perform_promotion { + # Stop current master + if [[ $DRY_RUN = false ]]; then + podman stop conjur-master-1.mycompany.local + fi + + # Promote Standby to Master + _run conjur-master-2.mycompany.local \ + "evoke role promote" + + # Repoint Standby to updated Master + _run conjur-master-3.mycompany.local \ + "evoke replication rebase conjur-master-2.mycompany.local" +} + +function _single_master { + _start_master + _configure_master + echo "DAP instance available at: 'https://localhost'" + echo "Login using with the username/password: 'admin'/'$_admin_password'" +} + +function _setup_standbys { + _setup_standby 2 + _setup_standby 3 + _setup_standby 4 + _setup_standby 5 + _start_standby_synchronization + + # Reload load balancer to serve cluster + _set_master_multi_node_proxy_config + + podman stop conjur-master.mycompany.local + podman rm conjur-master.mycompany.local + podman run --name conjur-master.mycompany.local \ + -d --privileged --restart=unless-stopped \ + --security-opt seccomp=unconfined \ + --publish "10443:443" \ + --publish "7000:7000" \ + --log-driver journald \ + --network dap_net \ + --volume master-certs:/etc/ssl/certs:Z \ + --volume ./files/haproxy/master:/usr/local/etc/haproxy:Z \ + haproxy:2.1-alpine +} + +function _command { + podman run --rm -w /dap-intro -v "$(pwd):/dap-intro" alpine "$@" +} + +function _stop { + echo "stopping...." + podman stop -a + podman rm -a + + _command rm -rf cli_cache + _command rm -rf system/backup + _command rm -rf system/logs + _command rm files/haproxy/master/haproxy.cfg || true + echo "stopped" + exit +} + +function _cli { + local _namespace=$1 + local _policy=$2 + + echo "Loading Policy '$_policy':" + cat $_policy + echo '' + echo "with command: 'conjur policy load $_namespace $_policy'" + echo '' + echo '' + + if [[ $DRY_RUN = false ]]; then + bin/podman-cli conjur policy load $_namespace $_policy + fi +} + +function _disable_autofailover { + _run conjur-master-5.mycompany.local "evoke cluster member remove conjur-master-5.mycompany.local" + _run conjur-master-4.mycompany.local "evoke cluster member remove conjur-master-4.mycompany.local" + _run conjur-master-3.mycompany.local "evoke cluster member remove conjur-master-3.mycompany.local" + _run conjur-master-2.mycompany.local "evoke cluster member remove conjur-master-2.mycompany.local" +} + +function _enable_autofailover { + autofailover=$(curl -k https://localhost:10444/info | jq -r .configuration.conjur.cluster_name) + + if [ "$autofailover" = 'production' ]; then + _run conjur-master-2.mycompany.local "evoke cluster enroll --reenroll --cluster-machine-name conjur-master-2.mycompany.local --master-name conjur-master-1.mycompany.local production" + _run conjur-master-3.mycompany.local "evoke cluster enroll --reenroll --cluster-machine-name conjur-master-3.mycompany.local --master-name conjur-master-1.mycompany.local production" + _run conjur-master-4.mycompany.local "evoke cluster enroll --reenroll --cluster-machine-name conjur-master-4.mycompany.local --master-name conjur-master-1.mycompany.local production" + _run conjur-master-5.mycompany.local "evoke cluster enroll --reenroll --cluster-machine-name conjur-master-5.mycompany.local --master-name conjur-master-1.mycompany.local production" + else + _cli root "policy/base.yml" + _cli conjur/cluster policy/cluster.yml + + _run conjur-master-1.mycompany.local "evoke cluster enroll --cluster-machine-name conjur-master-1.mycompany.local production" + _run conjur-master-2.mycompany.local "evoke cluster enroll --cluster-machine-name conjur-master-2.mycompany.local --master-name conjur-master-1.mycompany.local production" + _run conjur-master-3.mycompany.local "evoke cluster enroll --cluster-machine-name conjur-master-3.mycompany.local --master-name conjur-master-1.mycompany.local production" + _run conjur-master-4.mycompany.local "evoke cluster enroll --cluster-machine-name conjur-master-4.mycompany.local --master-name conjur-master-1.mycompany.local production" + _run conjur-master-5.mycompany.local "evoke cluster enroll --cluster-machine-name conjur-master-5.mycompany.local --master-name conjur-master-1.mycompany.local production" + fi +} + +function _stop_replication { + if [[ $(podman ps --quiet --filter "name=conjur-master-2.mycompany.local") ]]; then + _run conjur-master-2.mycompany.local "evoke replication stop" + fi + if [[ $(podman ps --quiet --filter "name=conjur-master-3.mycompany.local") ]]; then + _run conjur-master-3.mycompany.local "evoke replication stop" + fi + if [[ $(podman ps --quiet --filter "name=conjur-master-4.mycompany.local") ]]; then + _run conjur-master-4.mycompany.local "evoke replication stop" + fi + if [[ $(podman ps --quiet --filter "name=conjur-master-5.mycompany.local") ]]; then + _run conjur-master-5.mycompany.local "evoke replication stop" + fi +} + +function _stop_and_rename { + local container_name="$1" + local rename_to="$2" + podman stop $container_name + image_id=$(podman ps --all --quiet --filter "name=$container_name") + podman rename $image_id $rename_to +} + +function _upgrade_via_backup_restore { + upgrade_to="$1" + + autofailover=$(curl -k https://localhost/info | jq -r .configuration.conjur.cluster_name) + + if [ "$autofailover" = 'production' ]; then + _disable_autofailover + fi + _upgrade_master_via_backup_restore $upgrade_to +} + +function _stop_and_remove_master { + podman stop conjur-master-1.mycompany.local + podman rm conjur-master-1.mycompany.local +} + +function _restore_from_backup { + _stop_and_remove_master + _start_master + + # Unpack the backup with podman exec evoke unpack backup -k /opt/conjur/backup/key /opt/conjur/backup/ + _run conjur-master-1.mycompany.local 'evoke unpack backup --key /opt/conjur/backup/key /opt/conjur/backup/$(ls -1t /opt/conjur/backup | grep gpg | head -1)' + + # Configure the new master with podman exec evoke restore master + _run conjur-master-1.mycompany.local "evoke restore --accept-eula" +} + +function _upgrade_master_via_backup_restore { + upgrade_to="$1" + # Run evoke replication stop on existing standbys and followers + _stop_replication + + # Generate a backup on the existing master using evoke backup + _create_backup + + # Stop the existing master container with podman stop and rename + _stop_and_rename 'conjur-master-1.mycompany.local' 'conjur-master-1.mycompany.local_backup' + + # Start a container using the new version image (this will become the new master) + export VERSION=$upgrade_to + _restore_from_backup + + # Confirm master is healthy + # ... +} + +function _create_backup { + _run conjur-master-1.mycompany.local \ + "evoke backup" +} + +function _add_follower_proxy { + _run conjur-follower-1.mycompany.local \ + "evoke proxy add 12.16.23.15" +} + +function _trigger_master_failover_failover { + _run conjur-master-1.mycompany.local \ + "sv stop conjur" + echo 'Auto-failover takes about a minute to complete.' +} + +function _import_certificates { + bin/generate-certs + + local cert_path='/opt/cyberark/dap/configuration/certificates' + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --root $cert_path/ca-chain.pem" + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_master/dap-master-key.pem --set $cert_path/dap_master/dap-master.pem" + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem $cert_path/dap_follower/dap-follower.pem" +} + +function _rotate_certificates { + bin/generate-certs --rotate-server --force + + # Disable auto-failover while rotating the Master cluster certificates + # to prevent an unintended failover. + _pause_autofailover + + # Import the new certificate into the active DAP Master + local cert_path='/opt/cyberark/dap/configuration/certificates' + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_master/dap-master-key.pem --set $cert_path/dap_master/dap-master.pem" + + # Import the new Follower certificate into the active DAP master so that it + # is available through the seed service + _run conjur-master-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem $cert_path/dap_follower/dap-follower.pem" + + # Import the new certificate into the DAP Standbys + if [[ $(podman ps --quiet --filter "name=conjur-master-2.mycompany.local") ]]; then + _run conjur-master-2.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_master/dap-master-key.pem --set $cert_path/dap_master/dap-master.pem" + + # Import the new Follower certificate into each DAP Standby so that it + # is available through the seed service if the Standby is promoted. + _run conjur-master-2.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem $cert_path/dap_follower/dap-follower.pem" + fi + + if [[ $(podman ps --quiet --filter "name=conjur-master-3.mycompany.local") ]]; then + _run conjur-master-3.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_master/dap-master-key.pem --set $cert_path/dap_master/dap-master.pem" + + # Import the new Follower certificate into each DAP Standby so that it + # is available through the seed service if the Standby is promoted. + _run conjur-master-3.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem $cert_path/dap_follower/dap-follower.pem" + fi + + # Re-enable auto-failover for the Master cluster + _resume_autofailover + + if [[ $(podman ps --quiet --filter "name=conjur-follower-1.mycompany.local") ]]; then + # Import the new certificate into each Follower + _run conjur-follower-1.mycompany.local \ + "evoke ca import --force --key $cert_path/dap_follower/dap-follower-key.pem --set $cert_path/dap_follower/dap-follower.pem" + fi +} + +function _pause_autofailover { + autofailover=$(curl -k https://localhost/info | jq -r .configuration.conjur.cluster_name) + if [ "$autofailover" = 'production' ]; then + _run conjur-master-2.mycompany.local "sv down cluster" + _run conjur-master-3.mycompany.local "sv down cluster" + _run conjur-master-4.mycompany.local "sv down cluster" + _run conjur-master-5.mycompany.local "sv down cluster" + fi +} + +function _resume_autofailover { + autofailover=$(curl -k https://localhost/info | jq -r .configuration.conjur.cluster_name) + if [ "$autofailover" = 'production' ]; then + _run conjur-master-2.mycompany.local "sv up cluster" + _run conjur-master-3.mycompany.local "sv up cluster" + _run conjur-master-4.mycompany.local "sv up cluster" + _run conjur-master-5.mycompany.local "sv up cluster" + fi +} + +function _wait_for_master { + local master_url="https://localhost" + + echo "Waiting for DAP Master to be ready..." + + # Wait for 10 successful connections in a row + local COUNTER=0 + while [ $COUNTER -lt 10 ]; do + local response + response=$(curl -k --silent --head "$master_url/health" || true) + + if ! echo "$response" | grep -q "Conjur-Health: OK"; then + sleep 5 + COUNTER=0 + else + (( COUNTER=COUNTER+1 )) + fi + + sleep 1 + echo "Successful Health Checks: $COUNTER" + done +} + +create_podman_network() { + + # Cleanup any old, unused networks, including the previous DAP podman Compose + # networks. + podman network prune --force + + dap_net_pid=$(podman network ls --quiet --filter name=dap_net) + if [[ -z "$dap_net_pid" ]]; then + podman network create \ + --driver bridge \ + --subnet 12.16.23.0/27 \ + dap_net + fi +} + +TAG=5.0-stable +DRY_RUN=false +PULL_IMAGES=false +CMD="" +export DHPATH="${DHPATH:-/etc/ssl}" + +while true ; do + case "$1" in + --provision-master ) CMD='_single_master' ; shift ;; + --promote-standby ) CMD='_perform_promotion' ; shift ;; + --import-custom-certificates ) CMD='_import_certificates' ; shift ;; + --rotate-custom-certificates ) CMD='_rotate_certificates' ; shift ;; + --provision-standbys ) CMD='_setup_standbys' ; shift ;; + --enable-auto-failover ) CMD='_enable_autofailover' ; shift ;; + --provision-follower ) CMD='_setup_follower' ; shift ;; + --upgrade-master ) shift ; CMD="_upgrade_via_backup_restore $1" ; shift ;; + --version ) shift ; TAG=$1 ; shift ;; + --dry-run ) DRY_RUN=true ; shift ;; + -h | --help ) _print_help ; shift ;; + --trigger-failover ) CMD='_trigger_master_failover_failover' ; shift ;; + --create-backup ) CMD='_create_backup' ; shift ;; + --restore-from-backup ) CMD='_restore_from_backup' ; shift ;; + --trust-follower-proxy ) CMD='_add_follower_proxy' ; shift ;; + --wait-for-master ) CMD='_wait_for_master' ; shift ;; + --generate-dh ) export DHPATH=/tmp ; shift ;; + --stop ) _stop ; shift ;; + --add-standby ) shift ; CMD="_setup_standby $1" ; shift ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac +done + +export VERSION=$TAG + +create_podman_network + +eval $CMD diff --git a/bin/upgrade-test b/bin/upgrade-test new file mode 100755 index 00000000..5e45b092 --- /dev/null +++ b/bin/upgrade-test @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +set -eu + +# An upgrade test automation tool. +# +# Synopsis: bin/upgrade-test [intermediate-versions...] + +main() { + # Ensure at least two versions (an initial and final version) have been provided + if [ "$#" -lt 2 ]; then + print_help + fi + + # Pull off the initial cluster version + local initial_version=$1; shift; + + header "Stand Up Initial $initial_version Cluster" + standup_before_cluster "$initial_version" + echo + + header "Exercise $initial_version Cluster" + exercise_cluster "$initial_version" + echo + + header "Backup and Restore $initial_version Cluster" + backup_and_restore_cluster "$initial_version" + echo + + # Iterate through the next versions given to upgrade through them + for next_version in "$@" + do + header "Upgrade to $next_version" + upgrade_cluster "$next_version" + echo + + header "Exercise $initial_version Cluster" + exercise_cluster + echo + + header "Backup and Restore $next_version Cluster" + backup_and_restore_cluster "$next_version" + echo + + header "Exercise Upgraded and Restored $initial_version Cluster" + exercise_cluster + echo + done + + # After the last upgrade, ensure we can handle a failover + header "Failover Master" + failover_master + echo + + header "Exercise Cluster After Failover" + exercise_cluster + echo + + header "Tear Down Test Environment" + bin/dap --stop + echo + + echo "Upgrade test complete!" +} + +function print_help { + cat << EOF + +An upgrade test automation tool. + +Synopsis: bin/upgrade-test [intermediate-versions...] +EOF + exit +} + +standup_before_cluster() { + local version=$1 + + echo "Provisioning $version Master..." + bin/dap --provision-master --version "$version" + + # TODO: 3rd party certificates currently cause an error when attempting + # to load policy in dap-intro + # echo "Importing 3rd party certificates..." + # bin/dap --import-custom-certificates + + rollout_cluster "$version" +} + +exercise_cluster() { + echo "Loading policy..." + bin/api --load-sample-policy + + echo "Setting secret values..." + bin/api --set-secrets + + echo "Retrieving secret value from Master..." + bin/api --fetch-secrets --against-master + + echo "Retrieving secret value from Follower..." + bin/api --fetch-secrets + + echo "Deleting policy..." + bin/api --delete-policy +} + +failover_master() { + echo "Triggering a failover event..." + bin/dap --trigger-failover + + echo "Waiting for healthy Master..." + bin/dap --wait-for-master +} + +backup_and_restore_cluster() { + local version=$1 + + echo "Creating backup..." + bin/dap --create-backup + + echo "Restoring backup..." + bin/dap --restore-from-backup --version "$version" + + rollout_cluster "$version" +} + +upgrade_cluster () { + local version=$1 + + echo "Upgrading DAP Master to $version..." + bin/dap --upgrade-master "$version" + + rollout_cluster "$version" +} + +rollout_cluster() { + local version=$1 + + echo "Provisioning $version Standbys..." + bin/dap --provision-standbys --version "$version" + + echo "Enabling Auto-Failover..." + bin/dap --enable-auto-failover + + echo "Provisioning $version Follower" + bin/dap --provision-follower --version "$version" +} + +header() { + local message=$1 + + echo "---------------------------------------------" + echo "$message" + echo "---------------------------------------------" +} + +main "$@" diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 00000000..8078a8ad --- /dev/null +++ b/ci/README.md @@ -0,0 +1,35 @@ +# DAP End-to-End Tests + +For now, DAP-Intro includes a set of End-to-End tests. These tests are intended to validate common customer workflows. The current set of scenarios can be found [here](../features/cluster.feature). + +End-to-End tests are platform agnostic. This means the same set of scenarios are run against a set of supported environments. Docker Compose is the only currently supported environment. + +## Running End-to-End Tests + +To run the end-to-end test suite: + +``` +ci/bin/end-to-end-tests +``` + +## Adding new Release Versions + +When a new release candidate is ready to be added, three changes must be made in this repository: + +1. Add the version to line 5 of [/ci/bin/end-to-end-tests](../ci/bin/end-to-end-tests) +2. Update `CURRENT_VERSION` on line 6 in [/features/step_definitions/world.rb](../features/step_definitions/world.rb) +3. Add a the previously "Current" version to the `releases` table in [/features/cluster.feature](../features/cluster.feature) + +## Development + +These end-to-end tests were designed to be run against multiple environments and configurations. Currently, Docker Compose is the available provider. It's intended that cloud providers like AWS, Azure, and GCP are added in the future. We can also support additional runtime environments like Podman. + +### Adding a new Environment + +In order to implement a new environment, an environment specific provider must be created. This provider must implement the interface defined in [/ci/providers/provider_interface.rb](../ci/providers/provider_interface.rb). The Provider should handle both component setup (VM/LB provisioning and configuration) as well as inspection. [CI::Providers::DockerCompose](../ci/providers/docker_compose.rb) can be used as an example. + +Once the Provider has been completed, it must be added to: + +- [/features/step_definitions/world.rb](../features/step_definitions/world.rb) - sets provider for each run +- [/features/support/env.rb](../features/support/env.rb) - handles cleanup after all scenarios have been run +- [/ci/bin/end-to-end-tests](../ci/bin/end-to-end-tests) - list of providers to run tests against diff --git a/ci/assets/Dockerfile.ci b/ci/assets/Dockerfile.ci new file mode 100644 index 00000000..9f0b2f17 --- /dev/null +++ b/ci/assets/Dockerfile.ci @@ -0,0 +1,16 @@ +FROM ruby:2.7-alpine + +RUN apk update && apk add --no-cache docker-cli git libffi-dev build-base bash jq curl + +# Install Docker-Compose +RUN apk add --no-cache docker-cli python3 py3-pip && \ + apk add --no-cache --virtual .docker-compose-deps python3-dev libffi-dev openssl-dev gcc libc-dev make && \ + pip3 install docker-compose && \ + apk del .docker-compose-deps + +RUN mkdir -p /src +WORKDIR /src + +COPY Gemfile /src/Gemfile +COPY Gemfile.lock /src/Gemfile.lock +RUN bundle install diff --git a/ci/bin/end-to-end-tests b/ci/bin/end-to-end-tests new file mode 100755 index 00000000..0ca23c71 --- /dev/null +++ b/ci/bin/end-to-end-tests @@ -0,0 +1,47 @@ +#!/bin/bash -e +set -o pipefail + +# Array of versions to be used in testing +versions=('11.6.0' '11.7.0' '12.0.0') +# Array of providers to run end-to-end tests against +providers=('docker') + +prepare_environment() { + # With Docker in Docker, the network context seems not to be passed correctly. + # We'll create it here and provide it to the Docker Compose. + docker network prune --force + docker network create \ + --driver bridge \ + --ipam-driver default \ + --subnet 12.16.23.0/27 \ + dap_net + + # Docker in Docker container won't have permission to pull images, so + # we need to pull them before we start. + for version in "${versions[@]}"; do + docker pull registry.tld/conjur-appliance:$version + done + + # Build Docker in Docker image + docker build -t cucumber --file ci/assets/Dockerfile.ci . +} + + +main() { + # Prepare the exterior environment for Docker in Docker + prepare_environment + + for provider in "${providers[@]}"; do + docker run \ + --rm \ + -it \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --network dap_net \ + -v "$(pwd):$(pwd)" \ + --env PROVIDER=$provider \ + --workdir "$(pwd)" \ + cucumber /bin/bash -c "rake features" + done +} + +main diff --git a/ci/providers/docker_compose.rb b/ci/providers/docker_compose.rb new file mode 100644 index 00000000..737ef9d2 --- /dev/null +++ b/ci/providers/docker_compose.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require './ci/providers/provider_interface' + +require 'json' +require 'net/https' +require 'uri' + + +module CI + module Providers + # CI::Providers::DockerCompose enables Cucumber features to be run against + # DAP configured in Docker Compose. + # + # The DockerCompose class implements the public methods for the generic + # CI::Providers::Interface using Docker Compose. + class DockerCompose < ProviderInterface + + def initialize(logger:) + @logger = logger + end + + def provision_master(version:, with_load_balancer: true) + system('cp files/haproxy/master/single/haproxy.cfg files/haproxy/master/haproxy.cfg') + system({ 'VERSION' => version }, 'docker-compose up -d --no-deps conjur-master.mycompany.local conjur-master-1.mycompany.local') + args = [ + 'evoke configure master', + '--accept-eula', + '--hostname conjur-master.mycompany.local', + '--master-altnames conjur-master-1.mycompany.local,conjur-master-2.mycompany.local,conjur-master-3.mycompany.local', + '--admin-password MySecretP@ss1', + 'demo' + ].join(' ') + system("docker-compose exec conjur-master-1.mycompany.local bash -c '#{args}'") + end + + def provision_follower(version:, with_load_balancer: true) + system({ 'VERSION' => version }, 'docker-compose up --no-deps --detach conjur-follower-1.mycompany.local') + system('docker-compose exec conjur-master-1.mycompany.local bash -c "evoke seed follower conjur-follower.mycompany.local > /opt/cyberark/dap/seeds/follower-seed.tar"') + system('docker-compose exec conjur-follower-1.mycompany.local bash -c "evoke unpack seed /opt/cyberark/dap/seeds/follower-seed.tar && evoke configure follower"') + + # Start Load Balancer + system('docker-compose up -d --no-deps conjur-follower.mycompany.local') + end + + def reset_environment + system('bin/dap --stop') + end + + def import_custom_certificates + system('bin/dap --import-custom-certificates') + end + + def provision_standbys(version:) + system("bin/dap --provision-standbys --version #{version}") + end + + def enable_autofailover + system('bin/dap --enable-auto-failover') + end + + def trigger_auto_failover + system('bin/dap --trigger-failover') + end + + def master_connection + @connection ||= begin + http = Net::HTTP.new('conjur-master.mycompany.local', 443) + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + http + end + end + + def wait_for_healthy_master(sleep_for: 10) + sleep(5) + loop do + begin + response = master_connection.request(Net::HTTP::Get.new('/health')) + if response.is_a?(Net::HTTPSuccess) + response_message = JSON.parse(response.body) + + # Not sure if this is a bug, but following an auto-failover, we + # sometimes see the following in health: + # ``` + # ... + # "cluster": { + # "ok": true, + # "status": "standing_by", + # "message": null + # }, + # "ok": true + # ``` + # It seems to reset relatively quickly to the following: + # ``` + # ... + # "cluster": { + # "ok": true, + # "status": "running", + # "message": "acting as master" + # }, + # "ok": true + # ``` + if response_message['ok'] && + response_message['cluster']['status'] == 'running' + break + end + else + sleep(sleep_for) + end + rescue Exception => e + sleep(sleep_for) + end + end + end + + def current_master + response = master_connection.request(Net::HTTP::Get.new('/info')) + return nil unless response.is_a?(Net::HTTPSuccess) + + conjur_info = JSON.parse(response.body)['configuration']['conjur'] + + if conjur_info.key?('cluster_master') + return conjur_info['cluster_master'] + end + + 'conjur-master-1.mycompany.local' + end + + def last_audit_event + last_audit = `docker-compose exec #{current_master} bash -c "tail -n 1 /var/log/conjur/audit.json"` + + return JSON.parse(last_audit) unless last_audit.nil? + end + + def upgrade_master(version:) + system("bin/dap --upgrade-master #{version}") + end + end + end +end diff --git a/ci/providers/provider_interface.rb b/ci/providers/provider_interface.rb new file mode 100644 index 00000000..d83cf465 --- /dev/null +++ b/ci/providers/provider_interface.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module CI + module Providers + # This class implements the minimal set of methods a Provider must implement + # to ensure scenarios can be run. + class ProviderInterface + # def master_api; end + # + # def follower_api; end + + def provision_master(version:, with_load_balancer: true); raise 'method not implemen' end + + def provision_follower(version:, with_load_balancer: true); end + + def reset_environment; end + + def import_custom_certificates; end + + def teardown; end + + def provision_standbys(version:); end + + def enable_autofailover; end + + def trigger_auto_failover; end + + def wait_for_healthy_master; end + + def last_audit_event; end + + def upgrade_master(version:); end + end + end +end diff --git a/cipher-test b/cipher-test new file mode 100755 index 00000000..72d228fe --- /dev/null +++ b/cipher-test @@ -0,0 +1,26 @@ +#!/bin/bash -e + +# OpenSSL requires the port number. +SERVER=$1 +DELAY=1 +ciphers=$(openssl ciphers 'ALL:eNULL' | sed -e 's/:/ /g') + +echo Obtaining cipher list from $(openssl version). + +for cipher in ${ciphers[@]} +do +echo -n Testing $cipher... +result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1) +if [[ "$result" =~ ":error:" ]] ; then + error=$(echo -n $result | cut -d':' -f6) + echo NO \($error\) +else + if [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher :" ]] ; then + echo YES + else + echo UNKNOWN RESPONSE + echo $result + fi +fi +sleep $DELAY +done diff --git a/config/conjur.json b/config/conjur.json new file mode 100644 index 00000000..bd08692d --- /dev/null +++ b/config/conjur.json @@ -0,0 +1,13 @@ +{ + "postgresql": { + "config": { + "max_connections": 155, + "max_wal_senders": 55 + } + }, + "nginx": { + "ssl": { + "ciphers": "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256" + } + } +} diff --git a/conjur/cluster.yml b/conjur/cluster.yml new file mode 100644 index 00000000..6423a59f --- /dev/null +++ b/conjur/cluster.yml @@ -0,0 +1,92 @@ + + +- hosts: master_node + roles: + - role: cyberark.conjur + vars: + conjur_config: + host_fqdn: "conjur-1.mycompany.com" + master_cluster_fqdn: "conjur.mycompany.com" + type: "master" + account: "demo" + admin_password: "secret" + cluster_name: 'conjur-cluster' + master_key: "/path/to/key" + certs: + master_certificate: "" + master_key: "" + host_certificate: "" + host_key: "" + +- hosts: standby_node_1 + roles: + - role: cyberark.conjur + vars: + conjur_credentials: + hf_token: "" + resource_id: "" # alternative to hf_token when combinded with api_key + api_key: "" + conjur_config: + # master_host: master_node + host_fqdn: "conjur-2.mycompany.com" + master_cluster_fqdn: "conjur.mycompany.com" + type: "standby" + cluster_name: 'conjur-cluster' + master_key: "/path/to/key" + certs: + host_certificate: "" + host_key: "" + +- hosts: standby_node_2 + roles: + - role: cyberark.conjur + vars: + conjur_credentials: + hf_token: "" + resource_id: "" # alternative to hf_token when combinded with api_key + api_key: "" + conjur_config: + host_fqdn: "conjur-3.mycompany.com" + master_cluster_fqdn: "conjur.mycompany.com" + type: "standby" + cluster_name: 'conjur-cluster' + master_key: "/path/to/key" + certs: + host_certificate: "" + host_key: "" + +- hosts: dr_standby_node_1 + roles: + - role: cyberark.conjur + vars: + conjur_credentials: + hf_token: "" + resource_id: "" # alternative to hf_token when combinded with api_key + api_key: "" + conjur_config: + host_fqdn: "conjur-dr-1.mycompany.com" + master_cluster_fqdn: "conjur.mycompany.com" + type: "standby" + master_key: "/path/to/key" + certs: + host_certificate: "" + host_key: "" + + +- hosts: follower_node_1 + roles: + - role: cyberark.conjur + vars: + conjur_credentials: + hf_token: "" + resource_id: "" # alternative to hf_token when combinded with api_key + api_key: "" + conjur_config: + #master_host: master_node + host_fqdn: "conjur-follower-1.mycompany.com" + load_balancer_fqdn: "conjur.mycompany.com" + type: "follower" # master|standby|follower + master_key: "/path/to/key" + certs: + host_certificate: "" + host_key: "" diff --git a/conjur/conjur.yml b/conjur/conjur.yml new file mode 100644 index 00000000..8343e93a --- /dev/null +++ b/conjur/conjur.yml @@ -0,0 +1,54 @@ +--- +- hosts: localhost + vars: + master_nodes: + - name: master1 + port: 443 + - name: master2 + port: 444 + - name: master3 + port: 445 + - name: master4 + port: 446 + follower_nodes: + - name: follower1 + port: 447 + - name: follower2 + port: 448 + tasks: + - name: Create a network + docker_network: + name: conjur-network + + - name: Start Conjur containers + loop: "{{ master_nodes }}" + docker_container: + name: "conjur-{{ item.name }}" + image: 'registry.tld/conjur-appliance:5.0-stable' + security_opts: 'seccomp:unconfined' + published_ports: + - "{{ item.port }}:443" + networks: + - name: conjur-network + state: 'started' + + - name: Configure the master + shell: | + if [[ $(docker exec conjur-{{ master_nodes[0].name }} /bin/sh -c "evoke role") == 'blank' ]]; then + docker exec conjur-{{ master_nodes[0].name }} /bin/sh -c "evoke configure master -h conjur-{{master_nodes[0].name}} -p secret demo" + fi + + - name: Create Standby seeds and copy locally + loop: "{{ master_nodes[1:] }}" + shell: | + docker exec conjur-{{ master_nodes[0].name }} /bin/sh -c "evoke seed standby conjur-{{ item.name }} conjur-master1 > /opt/{{ item.name }}.tar" + docker cp conjur-{{ master_nodes[0].name }}:/opt/{{ item.name }}.tar tmp/{{ item.name }}.tar + + - name: Configure Standbys + loop: "{{ master_nodes[1:] }}" + shell: | + if [[ $(docker exec conjur-{{ item.name }} /bin/sh -c "evoke role") == 'blank' ]]; then + docker cp tmp/{{ item.name }}.tar conjur-{{ item.name }}:/opt/{{ item.name }}.tar + docker exec conjur-{{ item.name }} /bin/sh -c "evoke unpack seed /opt/{{ item.name }}.tar" + docker exec conjur-{{ item.name }} /bin/sh -c "evoke configure standby" + fi diff --git a/conjur/hosts.yml b/conjur/hosts.yml new file mode 100644 index 00000000..aeb2433d --- /dev/null +++ b/conjur/hosts.yml @@ -0,0 +1,50 @@ +all: + children: + conjur_autofailover_cluster_nodes: + hosts: + conjur-master-1.mycompany.local: + ansible_connection: docker + conjur_port: 443 + # tls_certificate: "{{ lookup('file', '/path/to/cert.pem') }}" + # tls_key: "{{ lookup('file', '/path/to/key.pem') }}" + conjur-master-2.mycompany.local: + ansible_connection: docker + conjur_port: 444 + # tls_certificate: "{{ lookup('file', '/path/to/cert.pem') }}" + # tls_key: "{{ lookup('file', '/path/to/key.pem') }}" + conjur-master-3.mycompany.local: + ansible_connection: docker + conjur_port: 445 + # tls_certificate: "{{ lookup('file', '/path/to/cert.pem') }}" + # tls_key: "{{ lookup('file', '/path/to/key.pem') }}" + + conjur_disaster_recovery_nodes: + hosts: + conjur-master-1.mycompany.local: + ansible_connection: docker + conjur_port: 446 + # tls_certificate: "{{ lookup('file', '/path/to/cert.pem') }}" + # tls_key: "{{ lookup('file', '/path/to/key.pem') }}" + + conjur_follower_nodes: + hosts: + conjur-follower.mycompany.local: + ansible_connection: docker + conjur_port: 447 + # tls_certificate: "{{ lookup('file', '/path/to/cert.pem') }}" + # tls_key: "{{ lookup('file', '/path/to/key.pem') }}" + + +# [conjur_autofailover_cluster_nodes] +# master1.mycompany.com tls_certificate="{{ lookup('file', '/path/to/cert.pem') }}" tls_key="{{ lookup('file', '/path/to/key.pem') }}" +# master2.mycompany.com tls_certificate="{{ lookup('file', '/path/to/cert.pem') }}" tls_key="{{ lookup('file', '/path/to/key.pem') }}" +# master3.mycompany.com tls_certificate="{{ lookup('file', '/path/to/cert.pem') }}" tls_key="{{ lookup('file', '/path/to/key.pem') }}" +# master4.mycompany.com tls_certificate="{{ lookup('file', '/path/to/cert.pem') }}" tls_key="{{ lookup('file', '/path/to/key.pem') }}" +# +# [conjur_disaster_recovery_nodes] +# master5.mycompany.com tls_certificate="{{ lookup('file', '/path/to/cert.pem') }}" tls_key="{{ lookup('file', '/path/to/key.pem') }}" +# master5.mycompany.com tls_certificate="{{ lookup('file', '/path/to/cert.pem') }}" tls_key="{{ lookup('file', '/path/to/key.pem') }}" +# +# [conjur_follower_nodes] +# follower1.mycompany.com tls_certificate="{{ lookup('file', '/path/to/cert.pem') }}" tls_key="{{ lookup('file', '/path/to/key.pem') }}" +# follower2.mycompany.com tls_certificate="{{ lookup('file', '/path/to/cert.pem') }}" tls_key="{{ lookup('file', '/path/to/key.pem') }}" diff --git a/conjur/local.yml b/conjur/local.yml new file mode 100644 index 00000000..f989d631 --- /dev/null +++ b/conjur/local.yml @@ -0,0 +1,154 @@ +# --- +# - name: Run using a project directory +# hosts: localhost +# gather_facts: no +# tasks: +# - docker_compose: +# project_src: ../demos/cluster +# state: present +# +--- +- hosts: localhost + # gather_facts: true + # become: true + tasks: + # - debug: + # msg: "{{ hostvars[item]['inventory_hostname'] }} - {{ hostvars[item]['conjur_port'] }}" + # loop: "{{ groups['conjur_autofailover_cluster_nodes'] }}" + + - name: Create a network + docker_network: + name: conjur-network + + - name: docker | Start Conjur containers + loop: "{{ groups['conjur_autofailover_cluster_nodes'] }}" + include_role: + name: common + vars: + hostname: "{{ hostvars[item]['inventory_hostname'] }}" + conjur_port: "{{ hostvars[item]['conjur_port'] }}" + container_network: conjur-network # only for local development + + - name: Configure master + # - hosts: "conjur-master-1.mycompany.local" + import_role: + role: conjur-master + vars: + conjur_config: + host_fqdn: "conjur-master-1.mycompany.local" + # master_cluster_fqdn: "conjur.mycompany.com" + master_cluster_fqdn: conjur-master-1.mycompany.local + type: "master" + account: "demo" + admin_password: "secret" + cluster_name: 'conjur-cluster' + standby_nodes: + - "conjur-master-2.mycompany.local" + - "conjur-master-3.mycompany.local" + + - debug: + msg: "standby hf token: {{ standby_host_factory_token }}" + + + - name: Configure standby + # - hosts: "conjur-master-1.mycompany.local" + import_role: + role: conjur-standby + vars: + conjur_config: + hf_token: "{{ standby_host_factory_token }}" + # image: "conjur-appliance:5.3" + host_fqdn: "conjur-master-2.mycompany.local" + # master_cluster_fqdn: "conjur.mycompany.com" + master_fqdn: "conjur-master-1.mycompany.local" + type: "standby" + cluster_name: 'conjur-cluster' + account: "demo" # this can be removed in favor of parsing enr + + + # - name: Configure standby + # import_role: + # - role: conjur-standby + # vars: + # conjur_config: + # hf_token: "{{ standby_host_factory_token }}" + # # image: "conjur-appliance:5.3" + # host_fqdn: "conjur-2.mycompany.com" + # # master_cluster_fqdn: "conjur.mycompany.com" + # master_fqdn: "conjur-1.mycompany.com" + # type: "standby" + # cluster_name: 'conjur-cluster' + + + # docker_container: + # name: "{{ hostvars[item]['inventory_hostname'] }}" + # image: 'registry.tld/conjur-appliance:5.0-stable' + # security_opts: 'seccomp:unconfined' + # published_ports: + # - "{{ hostvars[item]['conjur_port'] }}:443" + # networks: + # - name: conjur-network + # state: 'started' + + + + +# - name: Create a network +# docker_network: +# name: conjur-network + +# - name: Start Conjur containers +# hosts: conjur_autofailover_cluster_nodes +# gather_facts: no +# tasks: +# - loop: "{{ master_nodes }}" +# - docker_container: +# name: "conjur-{{ item.name }}" +# image: 'registry.tld/conjur-appliance:5.0-stable' +# security_opts: 'seccomp:unconfined' +# published_ports: +# - "{{ item.conjur_port }}:443" +# # networks: +# # - name: conjur-network +# state: 'started' + + + +# tasks: + # For encryption using a master key + # master_key_encryption: "{{ lookup('file', '/path/to/master-key') }}" + + # For encrypting using KMS + # kms_key_encryption: + # aws_access_key_id: '' + # aws_secret_access_key: '' + # ??: '' + + # For encryption using a master key + # hsm_encryption: + # library: '' + # wrapping_key: '' + # parameters: '' + # slot: '' + # pin: '' + +# - hosts: conjur_autofailover_cluster_nodes +# vars: +# master_cluster_fqdn: conjur.mycompany.com +# roles: +# - role: conjur +# vars: +# node_type: auto-failover +# # certificate_chain: "{{ lookup('file', '/path/to/cert_chain') }}" +# +# - hosts: conjur_disaster_recovery_nodes +# roles: +# - role: conjur +# vars: +# node_type: disaster-recovery +# +# - hosts: conjur_follower_nodes +# roles: +# - role: conjur +# vars: +# node_type: follower diff --git a/conjur/roles/common/tasks/main.yml b/conjur/roles/common/tasks/main.yml new file mode 100644 index 00000000..ee57f32c --- /dev/null +++ b/conjur/roles/common/tasks/main.yml @@ -0,0 +1,33 @@ +# This playbook covers common tasks that need to be run on all nodes + +- name: Start Conjur container (local) + when: container_network | default('') != '' + docker_container: + name: "{{ hostname | default('conjur') }}" + image: 'registry.tld/conjur-appliance:5.0-stable' + security_opts: 'seccomp:unconfined' + published_ports: + - "{{ conjur_port | default('443') }}:443" + networks: + - name: conjur-network + state: 'started' + +- name: Start Conjur container + when: container_network | default('') == '' + docker_container: + name: "{{ hostname | default('conjur') }}" + image: 'registry.tld/conjur-appliance:5.0-stable' + security_opts: 'seccomp:unconfined' + published_ports: + - "{{ conjur_port | default('443') }}:443" + state: 'started' + + + # name: 'conjur' + # image: 'registry.tld/conjur-appliance:5.0-stable' + # security_opts: 'seccomp:unconfined' + # published_ports: + # - "{{ conjur_port }}:443" + # interactive: yes + # # state: absent + # state: 'started' diff --git a/conjur/roles/conjur-master/README.md b/conjur/roles/conjur-master/README.md new file mode 100644 index 00000000..225dd44b --- /dev/null +++ b/conjur/roles/conjur-master/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/conjur/roles/conjur-master/defaults/main.yml b/conjur/roles/conjur-master/defaults/main.yml new file mode 100644 index 00000000..f4736633 --- /dev/null +++ b/conjur/roles/conjur-master/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for conjur \ No newline at end of file diff --git a/conjur/roles/conjur-master/files/cluster.yml b/conjur/roles/conjur-master/files/cluster.yml new file mode 100644 index 00000000..819bca01 --- /dev/null +++ b/conjur/roles/conjur-master/files/cluster.yml @@ -0,0 +1,30 @@ +# Create a Cluster service +- !policy + id: cluster/master-cluster + body: + - !layer + - !host-factory + layer: [ !layer ] + +# Create seed service +- !webservice seed-generation + +# Enable the seed service for hosts in the cluster layer +- !permit + role: !layer cluster/master-cluster + resource: !webservice seed-generation + privileges: [ "execute" ] + +# Create a follower layer +- !policy + id: followers + body: + - !layer + - !host-factory + layer: [ !layer ] + +# Enable the seed service for hosts in the followers layer +- !permit + role: !layer followers + resource: !webservice seed-generation + privileges: [ "execute" ] diff --git a/conjur/roles/conjur-master/files/root.yml b/conjur/roles/conjur-master/files/root.yml new file mode 100644 index 00000000..ba67d434 --- /dev/null +++ b/conjur/roles/conjur-master/files/root.yml @@ -0,0 +1,3 @@ +- !policy + id: conjur + diff --git a/conjur/roles/conjur-master/handlers/main.yml b/conjur/roles/conjur-master/handlers/main.yml new file mode 100644 index 00000000..c16e7165 --- /dev/null +++ b/conjur/roles/conjur-master/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for conjur \ No newline at end of file diff --git a/conjur/roles/conjur-master/meta/main.yml b/conjur/roles/conjur-master/meta/main.yml new file mode 100644 index 00000000..3a212a93 --- /dev/null +++ b/conjur/roles/conjur-master/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.4 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/conjur/roles/conjur-master/tasks/main.yml b/conjur/roles/conjur-master/tasks/main.yml new file mode 100644 index 00000000..6bba9a24 --- /dev/null +++ b/conjur/roles/conjur-master/tasks/main.yml @@ -0,0 +1,113 @@ +--- +# tasks file for conjur +- name: Check configuration state + register: raw_node_state + shell: docker exec {{ conjur_config.host_fqdn }} /bin/sh -c "evoke role" + +- set_fact: + config_state: "{{ raw_node_state.stdout }}" + +- debug: + msg: "node state: {{ config_state }}" + +- name: "Configure a Conjur master" + when: config_state == 'blank' + shell: | + if [[ $(docker exec {{ conjur_config.host_fqdn }} /bin/sh -c "evoke role") == 'blank' ]]; then + docker exec {{ conjur_config.host_fqdn }} /bin/sh -c "evoke configure master -h {{ conjur_config.master_cluster_fqdn }} -p {{ conjur_config.admin_password }} {{ conjur_config.account }}" + fi + +## TODO: How can we determine if this certificate is present? +- name: Create master altname certificate + shell: | + # Sketchy, hacky failure prevention + docker exec {{ conjur_config.host_fqdn }} /bin/sh -c "evoke ca issue {{ conjur_config.host_fqdn }}" | true + +## TODO: How can we determine if this certificate is present? +- name: Add Standby altnames + loop: "{{ standby_nodes }}" + shell: | + # Sketchy, hacky failure prevention + docker exec {{ conjur_config.host_fqdn }} /bin/sh -c "evoke ca issue {{ item }}" | true + +- name: Authenticate through API and retrieve API key + uri: + method: GET + url: https://localhost:{{ hostvars[conjur_config.host_fqdn]['conjur_port'] }}/authn/{{ conjur_config.account }}/login + # url: "http://localhost/authn/{{ conjur_config.account }}/login" + user: "admin" + password: "secret" + force_basic_auth: yes + validate_certs: no + return_content: yes + register: api_key + +- name: Authenticate through API and retrieve auth token + uri: + method: POST + url: https://localhost:{{ hostvars[conjur_config.host_fqdn]['conjur_port'] }}/authn/{{ conjur_config.account }}/admin/authenticate + # url: http://localhost:443/authn/{{ conjur_config.account }}/admin/authenticate + body: "{{ api_key['content'] }}" + validate_certs: no + return_content: yes + register: raw_auth_token + +- name: Set Conjur namespace + uri: + method: PUT + url: https://localhost:{{ hostvars[conjur_config.host_fqdn]['conjur_port'] }}/policies/{{ conjur_config.account }}/policy/root + # url: http://localhost:443/authn/{{ conjur_config.account }}/policies/{{ conjur_config.account }}/policy/root + headers: + Authorization: Token token="{{ raw_auth_token.content | b64encode | trim }}" + body: "{{ lookup('file','root.yml') }}" + status_code: 201 + validate_certs: no + +- name: Set a cluster namespace + uri: + method: PUT + url: https://localhost:{{ hostvars[conjur_config.host_fqdn]['conjur_port'] }}/policies/{{ conjur_config.account }}/policy/conjur + # url: http://localhost:443/authn/{{ conjur_config.account }}/policies/{{ conjur_config.account }}/policy/conjur + headers: + Authorization: Token token="{{ raw_auth_token.content | b64encode | trim }}" + body: "{{ lookup('file','cluster.yml') }}" + status_code: 201 + validate_certs: no + +# Dirty hack for generating future time in correct ISO 8601 format +- name: Calculate future time + shell: | + docker exec {{ conjur_config.host_fqdn }} /bin/sh -c "date -d \"+5 min\" +%FT%H:%M:%SZ" + register: raw_timestamp + +- name: Create Host Factory Token + uri: + method: POST + url: https://localhost:{{ hostvars[conjur_config.host_fqdn]['conjur_port'] }}/host_factory_tokens + # url: http://localhost:443/authn/{{ conjur_config.account }}/host_factory_tokens + headers: + Authorization: Token token="{{ raw_auth_token.content | b64encode | trim }}" + body: "expiration={{ raw_timestamp.stdout }}&\ + host_factory={{ conjur_config.account }}:host_factory:conjur%2fcluster%2fmaster-cluster" + validate_certs: no + register: hf_token_response + +- set_fact: + standby_host_factory_token: "{{ hf_token_response.json[0].token }}" + +- name: Enroll master into cluster layer + when: conjur_config.cluster_name + uri: + method: POST + url: https://localhost:{{ hostvars[conjur_config.host_fqdn]['conjur_port'] }}/host_factories/hosts + # url: http://localhost:443/authn/{{ conjur_config.account }}/host_factories/hosts + headers: + Authorization: Token token="{{ standby_host_factory_token }}" + body: "id=conjur/cluster/master-cluster/{{ conjur_config.host_fqdn }}" + validate_certs: no + status_code: 201 + +- name: Enroll into auto-failover cluster + when: conjur_config.cluster_name + shell: | + docker exec {{ conjur_config.host_fqdn }} /bin/sh -c "evoke cluster enroll -n {{ conjur_config.host_fqdn }} master-cluster | true" diff --git a/conjur/roles/conjur-master/tasks/testing.yml b/conjur/roles/conjur-master/tasks/testing.yml new file mode 100644 index 00000000..198e1c30 --- /dev/null +++ b/conjur/roles/conjur-master/tasks/testing.yml @@ -0,0 +1,2 @@ +- debug: + msg: "got it" diff --git a/conjur/roles/conjur-master/tests/inventory b/conjur/roles/conjur-master/tests/inventory new file mode 100644 index 00000000..878877b0 --- /dev/null +++ b/conjur/roles/conjur-master/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/conjur/roles/conjur-master/tests/test.yml b/conjur/roles/conjur-master/tests/test.yml new file mode 100644 index 00000000..ef7a8705 --- /dev/null +++ b/conjur/roles/conjur-master/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - conjur \ No newline at end of file diff --git a/conjur/roles/conjur-master/vars/main.yml b/conjur/roles/conjur-master/vars/main.yml new file mode 100644 index 00000000..01a5a686 --- /dev/null +++ b/conjur/roles/conjur-master/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for conjur \ No newline at end of file diff --git a/conjur/roles/conjur-standby/README.md b/conjur/roles/conjur-standby/README.md new file mode 100644 index 00000000..225dd44b --- /dev/null +++ b/conjur/roles/conjur-standby/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/conjur/roles/conjur-standby/defaults/main.yml b/conjur/roles/conjur-standby/defaults/main.yml new file mode 100644 index 00000000..b585d5dd --- /dev/null +++ b/conjur/roles/conjur-standby/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for conjur-standby \ No newline at end of file diff --git a/conjur/roles/conjur-standby/handlers/main.yml b/conjur/roles/conjur-standby/handlers/main.yml new file mode 100644 index 00000000..5ec0bd4c --- /dev/null +++ b/conjur/roles/conjur-standby/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for conjur-standby \ No newline at end of file diff --git a/conjur/roles/conjur-standby/meta/main.yml b/conjur/roles/conjur-standby/meta/main.yml new file mode 100644 index 00000000..3a212a93 --- /dev/null +++ b/conjur/roles/conjur-standby/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.4 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/conjur/roles/conjur-standby/tasks/main.yml b/conjur/roles/conjur-standby/tasks/main.yml new file mode 100644 index 00000000..7fe58388 --- /dev/null +++ b/conjur/roles/conjur-standby/tasks/main.yml @@ -0,0 +1,43 @@ +--- +- name: Check configuration state + register: raw_node_state + shell: docker exec {{ conjur_config.host_fqdn }} /bin/sh -c "evoke role" + +- set_fact: + config_state: "{{ raw_node_state.stdout }}" + +- debug: + msg: "node state: {{ config_state }}" + +- name: Enroll Standby into layer + when: config_state == 'blank' + uri: + method: POST + url: https://localhost:{{ hostvars[conjur_config.master_fqdn]['conjur_port'] }}/host_factories/hosts + # url: http://localhost:443/authn/{{ conjur_config.account }}/host_factories/hosts + headers: + Authorization: Token token="{{ standby_host_factory_token }}" + body: "id=conjur/cluster/master-cluster/{{ conjur_config.host_fqdn }}" + validate_certs: no + status_code: 201 + register: enrollment_response + +- set_fact: + escaped_hostname: "host%2Fconjur%2Fcluster%2Fmaster-cluster%2F{{ conjur_config.host_fqdn }}" + +- name: Authenticate through API and retrieve auth token + when: config_state == 'blank' + uri: + method: POST + url: https://localhost:{{ hostvars[conjur_config.master_fqdn]['conjur_port'] }}/authn/{{ conjur_config.account }}/{{ escaped_hostname }}/authenticate + # url: http://localhost:443/authn/{{ conjur_config.account }}/admin/authenticate + body: "{{ enrollment_response.json.api_key }}" + validate_certs: no + return_content: yes + register: raw_auth_token + +- name: "Configure Standby" + when: config_state == 'blank' + shell: | + curl -k -X POST -H 'Authorization: Token token="{{ raw_auth_token.content | b64encode | trim }}"' -d '' https://localhost:{{ hostvars[conjur_config.master_fqdn]['conjur_port'] }}/configuration/{{ conjur_config.account }}/seed/standby | docker exec -it {{ conjur_config.host_fqdn }} evoke unpack seed - + docker exec {{ conjur_config.host_fqdn }} evoke configure standby diff --git a/conjur/roles/conjur-standby/tests/inventory b/conjur/roles/conjur-standby/tests/inventory new file mode 100644 index 00000000..878877b0 --- /dev/null +++ b/conjur/roles/conjur-standby/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/conjur/roles/conjur-standby/tests/test.yml b/conjur/roles/conjur-standby/tests/test.yml new file mode 100644 index 00000000..25440f97 --- /dev/null +++ b/conjur/roles/conjur-standby/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - conjur-standby \ No newline at end of file diff --git a/conjur/roles/conjur-standby/vars/main.yml b/conjur/roles/conjur-standby/vars/main.yml new file mode 100644 index 00000000..aef30cbf --- /dev/null +++ b/conjur/roles/conjur-standby/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for conjur-standby \ No newline at end of file diff --git a/conjur/roles/master/tasks/configure.yml b/conjur/roles/master/tasks/configure.yml new file mode 100644 index 00000000..e69de29b diff --git a/conjur/site.yml b/conjur/site.yml new file mode 100644 index 00000000..c93c89bf --- /dev/null +++ b/conjur/site.yml @@ -0,0 +1,3 @@ +- hosts: all + roles: + - role: common diff --git a/conjur/standby.yml b/conjur/standby.yml new file mode 100644 index 00000000..e69de29b diff --git a/curl_examples/check b/curl_examples/check new file mode 100755 index 00000000..3177ebfc --- /dev/null +++ b/curl_examples/check @@ -0,0 +1,43 @@ +#!/bin/bash -e + +function authentication_token { + user="$1" + api_key="$2" + raw_token="$(curl -k -X POST -d $api_key https://localhost/authn/test/$user/authenticate)" + token=$(echo -n $raw_token | base64 | tr -d '\r\n') + echo "$token" +} + +function user_authentication_token { + user="$1" + api_key="$(curl -k --user admin:secret https://localhost/authn/test/login)" + token=$(authentication_token $user $api_key) + echo "$token" +} + +# Authenticate with a user +auth_token=$(user_authentication_token "admin") + +secret="production/myapp/database/username" +encoded_secret="production%2Fmyapp%2Fdatabase%2Fusername" + +# Set a variable +resp=$(curl -k \ + -X POST \ + -H "Authorization: Token token=\"$auth_token\"" \ + --data "foo-bar" \ + "https://localhost/secrets/test/variable/$encoded_secret") + +# Retrieve variable value +resp=$(curl -k \ + -H "Authorization: Token token=\"$auth_token\"" \ + "https://localhost/secrets/test/variable/$encoded_secret") + +echo "$resp" + + +# Authenticate with a host +host="host%2Ftest-host-1" +api_key="" +auth_token=$(authentication_token $host $api_key) +echo "$auth_token" diff --git a/demos/aws-authentication/README.md b/demos/aws-authentication/README.md new file mode 100644 index 00000000..b836718b --- /dev/null +++ b/demos/aws-authentication/README.md @@ -0,0 +1,146 @@ +# Conjur AWS Authentication Demo + +## Overview +This demonstration highlights the ability of Conjur to leverage existing AWS IAM roles as a mechanism of authentication. + + +## The Demo + +1. Log into Conjur +2. Show Authenticator Policy +3. Show RDS Rotator +4. Lambda API endpoint to retrieve RDS credentials + + + +## The Parts + +* Conjur V5 Appliance + * Image uploaded to an S3 bucket - jv-conjur-demo + * EC2 instance (or ECS instance?) - ami-a4dc46db + +* RDS Instance + +* Lambda Function + - + +IAM Role + - + + +## Actions +* Pull down most recent Conjur Appliance and save it to a `tar` file. + ```sh + $ docker pull registry.tld/conjur-appliance:5.0.0-rc1 + $ docker save -o conjur-v5-rc1.tar registry.tld/conjur-appliance:5.0.0-rc1 + ``` +* Create an S3 bucket (ex. `conjur-development-releases`) +* Created Role (`conjur-role`) with policy permission to access the S3 bucket to download the Conjur Image: + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["s3:ListBucket"], + "Resource": ["arn:aws:s3:::conjur-development-releases"] + }, + { + "Effect": "Allow", + "Action": [ + "s3:GetObject" + ], + "Resource": ["arn:aws:s3:::conjur-development-releases/*"] + } + ] + } + ``` + +* Upload tar (ex. `conjur-v5-rc1.tar`) into the S3 bucket. +* Make sure you have the pem for EC2 instance: + ```sh + $ cp ~/Downloads/jason-conjur-test.pem . + $ chmod 600 jason-conjur-test.pem + $ ssh -i jason-conjur-test.pem ubuntu@34.232.68.235 + + # run on EC2 Instance + $ sudo apt-get update + $ sudo apt install -y awscli + $ sudo mkdir /src + $ sudo aws s3 cp s3://conjur-development-releases/conjur-v5-rc1.tar /src/ + + $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + $ sudo apt-get update + $ sudo apt-get install -y docker-ce + + $ sudo docker load --input /src/conjur-v5-rc1.tar + $ sudo docker run --name conjur -d --restart=always --security-opt seccomp:unconfined -p "443:443" -e "CONJUR_AUTHENTICATORS=authn-iam/staging" registry.tld/conjur-appliance:5.0.0-rc1 + sudo docker exec conjur evoke configure master --accept-eula -h ec2-34-224-2-198.compute-1.amazonaws.com -p secret demo + ``` + +* Load Policy (locally, after setting the `host` variable in the `./cli` file) + ``` + ./cli conjur policy load --replace root policy/users.yml + ./cli conjur policy load root policy/policy.yml + ./cli conjur policy load root policy/staging-iam-policy.yml + ./cli conjur policy load root policy/staging-myapp.yml + ./cli conjur policy load staging policy/database.yml + ./cli conjur policy load root policy/entitlements.yml + ./cli conjur variable values add staging/postgres-database/url test-url + ``` + +Launch a remote node + ``` + $ ssh -i jason-conjur-test.pem ubuntu@52.87.89.237 + $ sudo apt-get update + $ sudo apt-get install -y ruby ruby-dev build-essential + + $ scp -i jason-conjur-test.pem cli_cache/conjur-demo.pem ubuntu@52.87.89.237:/home/ubuntu/conjur-demo.pem + + + $ sudo gem install sinatra --no-rdoc --no-ri + $ sudo gem install aws-sdk --no-rdoc --no-ri + $ sudo gem install conjur-api --no-rdoc --no-ri + ``` + +Ruby test code +```ruby +require 'aws-sigv4' +require 'aws-sdk' + +request = Aws::Sigv4::Signer.new( + service: 'sts', + region: 'us-east-1', + credentials_provider: Aws::InstanceProfileCredentials.new +).sign_request( + http_method: 'GET', + url: 'https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15' +).headers + +require 'conjur-api' + +Conjur.configuration.account = 'demo' +Conjur.configuration.appliance_url = 'https://ec2-34-224-2-198.compute-1.amazonaws.com' +Conjur.configuration.authn_url = Conjur.configuration.appliance_url + '/authn-iam/staging' +Conjur.configuration.cert_file = '/home/ubuntu/conjur-demo.pem' +Conjur.configuration.apply_cert_config! + +# conjur = Conjur::API.new_from_key 'host/myapp/011915987442/MyApp', request.to_json +conjur = Conjur::API.new_from_key('host/staging-myapp/F888977921603/staging-myapp-ec2', request.to_json) +conjur.token + +#resource("cucumber:variable:db-password").value +username = conjur.resource('cucumber:variable:myapp/database/username').value +password = conjur.resource('cucumber:variable:myapp/database/password').value + +print("\nUsername: #{username} Password: #{password}\n\n") + +# Conjur.configuration.account = 'demo' +# Conjur.configuration.appliance_url = 'https://ec2-34-224-2-198.compute-1.amazonaws.com' +# Conjur.configuration.cert_file = '/home/ubuntu/conjur-demo.pem' +# Conjur.configuration.apply_cert_config! + +# conjur = Conjur::API.new_from_key('host/staging-myapp/F888977921603/staging-myapp-ec2', request.to_json) +# conjur.token +``` diff --git a/demos/aws-authentication/cli b/demos/aws-authentication/cli new file mode 100755 index 00000000..9c5b3580 --- /dev/null +++ b/demos/aws-authentication/cli @@ -0,0 +1,21 @@ +#!/bin/bash -e + +host="https://ec2-34-224-2-198.compute-1.amazonaws.com" + +cmd="$@" +docker run \ + --rm \ + -it \ + --entrypoint /bin/bash \ + -e "CONJUR_APPLIANCE_URL=$host" \ + -e "CONJUR_ACCOUNT=demo" \ + -e "CONJUR_AUTHN_LOGIN=admin" \ + -v "$(pwd)/policy:/policy" \ + -v "$(pwd)/cli_cache:/root" \ + cyberark/conjur-cli:5 -c " + if [ ! -e /root/conjur-demo.pem ]; then + conjur init -u $host + fi + conjur authn login -u admin -p secret + eval exec \"$cmd\" + " diff --git a/demos/aws-authentication/conjur-iam.json b/demos/aws-authentication/conjur-iam.json new file mode 100644 index 00000000..04da31a4 --- /dev/null +++ b/demos/aws-authentication/conjur-iam.json @@ -0,0 +1,17 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["s3:ListBucket"], + "Resource": ["arn:aws:s3:::jv-conjur-demo"] + }, + { + "Effect": "Allow", + "Action": [ + "s3:GetObject" + ], + "Resource": ["arn:aws:s3:::jv-conjur-demo/*"] + } + ] + } diff --git a/demos/aws-authentication/docker-compose.yml b/demos/aws-authentication/docker-compose.yml new file mode 100644 index 00000000..08a02604 --- /dev/null +++ b/demos/aws-authentication/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3" +services: + + client: + image: conjurinc/cli5 + working_dir: -w /src/cli + environment: + CONJUR_APPLIANCE_URL: https://conjur + CONJUR_ACCOUNT: test + CONJUR_AUTHN_LOGIN: admin + links: + - conjur:conjur + volumes: + - ./cli_cache:/root diff --git a/demos/aws-authentication/iam-test.rb b/demos/aws-authentication/iam-test.rb new file mode 100644 index 00000000..e8f45216 --- /dev/null +++ b/demos/aws-authentication/iam-test.rb @@ -0,0 +1,28 @@ +require 'aws-sigv4' +require 'aws-sdk' +require 'conjur-api' + +request = Aws::Sigv4::Signer.new( + service: 'sts', + region: 'us-east-1', + credentials_provider: Aws::InstanceProfileCredentials.new +).sign_request( + http_method: 'GET', + url: 'https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15' +).headers + +Conjur.configuration.account = 'demo' +Conjur.configuration.appliance_url = 'https://ec2-34-224-2-198.compute-1.amazonaws.com' +Conjur.configuration.authn_url = Conjur.configuration.appliance_url + '/authn-iam/staging' +Conjur.configuration.cert_file = '/home/ubuntu/conjur-demo.pem' +Conjur.configuration.apply_cert_config! + +# conjur = Conjur::API.new_from_key 'host/myapp/011915987442/MyApp', request.to_json +conjur = Conjur::API.new_from_key('host/staging-myapp/888977921603/staging-myapp-ec2', request.to_json) +conjur.token + +#resource("cucumber:variable:db-password").value +username = conjur.resource('cucumber:variable:myapp/database/username').value +password = conjur.resource('cucumber:variable:myapp/database/password').value + +print("\nUsername: #{username} Password: #{password}\n\n") diff --git a/demos/aws-authentication/jason-conjur-test.pem b/demos/aws-authentication/jason-conjur-test.pem new file mode 100644 index 00000000..29f043a3 --- /dev/null +++ b/demos/aws-authentication/jason-conjur-test.pem @@ -0,0 +1,23 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA1vi0+hTS6+58c4x8VgHFbGKJExgH/vQgp7ni2xL9x+9tdLrzc2psv6zjUHoJ +2YLt0vUw+Th4pZg99KL51dhVhAOTa/yq7kSjkRxNbosGVFaom7jSDfeJJPI61fgiXoAsRWeJqMWc +1EY8bKGABOK/NoJb66hRrbHxQNCqsyeEIIXfcwwdGJtwHKKm6Ny9xGVy9wnDR/07zWKaGV0oiNyv +KLTz1eZUhBaIzrC1wBz3ZjnG9qwafBD4pZ/o+9tWrTQBDe9vpKFNcJC9MGKtqZ1+JnBHuqQYGiti +fiUqh9MMnMHEdpFeAJvxwsgXd3Ajl55+WfswWa1XY46VaIbLZEaJ9wIDAQABAoIBAEMG1NbMu18Y +wvD8MqBWeQnsRzUO3x9dWvkw+ky4RSybuJMW32VzH2k8LLwg8QVCz4hhLt3l/6gSKe8nCaLlivRY +cRTQeTNFb4KFQpde/aA6TOQQ4l28eqRsam/gqEayzBrvx3o580Y0iA6O5G2hjWEfkC2QE7eGreQ5 +q5+kiIvi3zulIlS5y+O0o7zgWEgve3H/d6HP+/7pPQ+Ul5uZMU01zpTixqq7iP6acoNwpPfbwnnX +XW3UfVp1wivSyPeu+nUGYoNzcmGzdsdXHSnepIOeYRr/ak/u8kqRSVP93BesdeDfx8MoVraNnQMd +DxWk1xfFONeO1nyZRlQukkrU35ECgYEA+7nqzr071UaXnTIiUM3UvqL1YyPVdkFV42k9BdJAbE6l +DRlhaXp3rEjabLxYQRv5N5F67UXDBMNo91sC0OF76g3W2fDJFlek39Gj/glKHTLX2M3qJMYsycs3 +uLy5BszRmJGoQtp47ZVFtgUreYzTRdG8Lmr8dEBus2W3fa7clRsCgYEA2p8Kuw2Foe7q2PxCJBfE +jOviV8GjjVWpfbmNEL7ectRcRoSTm1CNZo5c+Ul8S1fy6BMPQnHjrJYuEOdeAzi9WZMqdKfEmSc6 +/IewLBGISvLoYPnmQjajSeDCv/peMyUY9/xkgBBcknx7i7UK1PRrZXm8DkZ9/1UjzhkZPRqTmFUC +gYBFhoshAMkm1fGIPFGYCdGpua6W7E3H9LG5Ntbg5bpfb7VMkecC0A1/qzuQ7tBdY1GJFIhkQnFj +vmkecKetc6na8mmWFlgj8J8cJnXp8zziJanSOsVh1M6ICbXhM1bTVvzI6+oSVO8zh5gSdwkT8F5m +GVClbW0+2pD4wa5Va1eHYwKBgAierLWjWtl/qhLUH2d86GsGAe6j2+b+sagbYMyAOhUc+mZtY8SD +8I9SnafWlegCl7k+xyM/ilKLuVVBShumaRDXFJ103/OJ8HF0iCW0q0MJQNBSChoiPV30VrlrDbvG +gq2EbhH+kyfTcKuZf8vVt0ZQ/nExplYi7T57Dtux6I/hAoGBAOKnBK/fTABeDZmG19f/kFBu4iug +OTRszsuqamUxCv7LsS2AmGRqTYffoQsReDauCszABDw86YgVfnFn+x7kQF1bW+3bSEqqByMFF7pf +O0hmeIfXQL9V8U0CbQqq9SCg+QQW/XFzqhulAL67zYsRJ9nqnlA6rpb/vNgyPQJZ0MBN +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/demos/aws-authentication/policy/database.yml b/demos/aws-authentication/policy/database.yml new file mode 100644 index 00000000..0b4805ee --- /dev/null +++ b/demos/aws-authentication/policy/database.yml @@ -0,0 +1,35 @@ +- !policy + id: postgres-database + body: + - &variables + - !variable url + - !variable username + - !variable + id: password + annotations: + rotation/rotator: postgresql/password + rotation/ttl: PT10M + rotation/postgresql/password/length: 32 + + # Create a group that will have permission to retrieve variables + - !group secrets-users + + # Create a group that will have permission to manage variables + - !group secrets-managers + + # Give the `secrets-users` group permission to retrieve variables + - !permit + role: !group secrets-users + privilege: [ read, execute ] + resource: *variables + + # Give the `secrets-managers` group permission to update variables + - !permit + role: !group secrets-managers + privilege: [ update ] + resource: *variables + + # Give the `secrets-managers` group read and execute permission as well as update + - !grant + member: !group secrets-managers + role: !group secrets-users diff --git a/demos/aws-authentication/policy/entitlements.yml b/demos/aws-authentication/policy/entitlements.yml new file mode 100644 index 00000000..b4b34723 --- /dev/null +++ b/demos/aws-authentication/policy/entitlements.yml @@ -0,0 +1,9 @@ +# Give all hosts in the layer the abilitity to authenticate +- !grant + role: !group conjur/authn-iam/staging/clients + member: !host staging-myapp/888977921603/staging-myapp-ec2 + +# Give the host in our layer permission to retrieve variables +- !grant + member: !layer staging-myapp/myapp + role: !group staging/postgres-database/secrets-users diff --git a/demos/aws-authentication/policy/policy.yml b/demos/aws-authentication/policy/policy.yml new file mode 100644 index 00000000..17a09ae6 --- /dev/null +++ b/demos/aws-authentication/policy/policy.yml @@ -0,0 +1,11 @@ +# Top-level policy file + +# Define "staging" namespace, owned by the "team_leads" +- !policy + id: staging + owner: !group team_leads + +# Define "production" namespace, owned by the "security_ops" team +- !policy + id: production + owner: !group security_ops diff --git a/demos/aws-authentication/policy/staging-iam-policy.yml b/demos/aws-authentication/policy/staging-iam-policy.yml new file mode 100644 index 00000000..df6838ad --- /dev/null +++ b/demos/aws-authentication/policy/staging-iam-policy.yml @@ -0,0 +1,12 @@ + +- !policy + id: conjur/authn-iam/staging + body: + - !webservice + + - !group clients + + - !permit + role: !group clients + privilege: [ read, authenticate ] + resource: !webservice diff --git a/demos/aws-authentication/policy/staging-myapp.yml b/demos/aws-authentication/policy/staging-myapp.yml new file mode 100644 index 00000000..c0c79892 --- /dev/null +++ b/demos/aws-authentication/policy/staging-myapp.yml @@ -0,0 +1,19 @@ + +--- +- !policy + id: staging-myapp + body: + # Create a layer to hold this application's hosts + - !layer myapp + + # Create a host using the namespace `aws` to identify this as an AWS resource. + # The host ID needs to match the AWS ARN of the role we wish to to authenticate. + - !host 888977921603/staging-myapp-ec2 + - !host 888977921603/staging-myapp-lambda + + # Add our hosts into our layer + - !grant + role: !layer myapp + members: + - !host 888977921603/staging-myapp-ec2 + - !host 888977921603/staging-myapp-lambda diff --git a/demos/aws-authentication/policy/users.yml b/demos/aws-authentication/policy/users.yml new file mode 100644 index 00000000..ddf4b093 --- /dev/null +++ b/demos/aws-authentication/policy/users.yml @@ -0,0 +1,72 @@ +- !group security_ops +- !group team_leads +- !group developers + +- !user + id: jason.vanderhoof + annotations: + first_name: Jason + last_name: Vanderhoof + email: jason.vanderhoof@cyberark.com + +- !user + id: marcel.calisto + annotations: + first_name: Marcel + last_name: Calisto + email: marcel.calisto@cyberark.com + +- !user + id: ernest.alvin + annotations: + first_name: Ernest + last_name: Alvin + email: ernest.alvin@cyberark.com + +- !user + id: victoria.nandita + annotations: + first_name: Victoria + last_name: Nandita + email: victoria.nandita@cyberark.com + +- !user + id: sophie.madelon + annotations: + first_name: Sophie + last_name: Madelon + email: sophie.madelon@cyberark.com + +- !user + id: terrance.blake + annotations: + first_name: Terrance + last_name: Blake + email: terrance.blake@cyberark.com + +- !grant + role: !group developers + members: + - !user marcel.calisto + - !user ernest.alvin + - !user sophie.madelon + +- !grant + role: !group team_leads + members: + - !user jason.vanderhoof + - !user victoria.nandita + +- !grant + role: !group security_ops + members: + - !user terrance.blake + +# Grant the less-powerful groups to the more-powerful groups +- !grant + member: !group team_leads + role: !group developers + +- !grant + member: !group security_ops + role: !group team_leads diff --git a/demos/aws-cluster/.gitignore b/demos/aws-cluster/.gitignore new file mode 100644 index 00000000..aa85e237 --- /dev/null +++ b/demos/aws-cluster/.gitignore @@ -0,0 +1,7 @@ +tmp/ +*.tfstate +*.tfstate.backup +.DS_Store +*.pem +terraform.tfvars +.terraform/ diff --git a/demos/aws-cluster/0_terraform_aws b/demos/aws-cluster/0_terraform_aws new file mode 100755 index 00000000..8cfba77a --- /dev/null +++ b/demos/aws-cluster/0_terraform_aws @@ -0,0 +1,13 @@ +#!/bin/bash -eu + +echo "Creating temporary directory for terraform plan..." +mkdir -p ./tmp/terraform + +# Make sure terraform dependencies and modules are loaded +terraform init + +# Generate the terraform execution plan +terraform plan -out=./tmp/terraform/conjur-ha.plan + +# Execute the plan to create the AWS resources +terraform apply ./tmp/terraform/conjur-ha.plan diff --git a/demos/aws-cluster/1.1_init_followers b/demos/aws-cluster/1.1_init_followers new file mode 100755 index 00000000..9c817469 --- /dev/null +++ b/demos/aws-cluster/1.1_init_followers @@ -0,0 +1,64 @@ +#!/bin/bash -eux + +: ${SSH_KEY_FILE?"Need to set SSH_KEY_FILE"} + +source bin/lib/aws_context +source bin/lib/conjur_context + +SEED_DIR="./tmp/conjur/seeds" + +function create_follower_seed() { + local filename=$1 + + mkdir -p $SEED_DIR + + # Create Follower Seed + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$MASTER_1_PUBLIC /bin/bash << EOF + docker exec conjur-appliance bash -c " \ + evoke seed follower "$LB_FOLLOWER_DNS" "$LB_DNS" > "/opt/conjur/backup/$filename" + " +EOF + + # Copy seed to host + scp -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "core@$MASTER_1_PUBLIC:/opt/conjur/backup/$filename" \ + "$SEED_DIR/$filename" +} + +function configure_follower() { + local follower_public=$1 + local filename=$2 + + # Copy seed + scp -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "$SEED_DIR/$filename" \ + "core@$follower_public:~/$filename" + + # Configure node + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$follower_public /bin/bash << EOF + sudo mv "\$HOME/$filename" "/opt/conjur/backup/$filename" + + docker exec conjur-appliance \ + evoke unpack seed "/opt/conjur/backup/$filename" + + docker exec conjur-appliance \ + evoke configure follower +EOF +} + +function configure_followers() { + for follower in $FOLLOWERS_PUBLIC; do + echo "Configuring follower on '$follower'..." + configure_follower "$follower" "follower-seed.tar" + done +} + +create_follower_seed "follower-seed.tar" + +configure_followers \ No newline at end of file diff --git a/demos/aws-cluster/100_cleanup_aws b/demos/aws-cluster/100_cleanup_aws new file mode 100755 index 00000000..da13bbdc --- /dev/null +++ b/demos/aws-cluster/100_cleanup_aws @@ -0,0 +1,3 @@ +#!/bin/bash -eu + +terraform destroy diff --git a/demos/aws-cluster/1_init_cluster b/demos/aws-cluster/1_init_cluster new file mode 100755 index 00000000..530faffd --- /dev/null +++ b/demos/aws-cluster/1_init_cluster @@ -0,0 +1,175 @@ +#!/bin/bash -eu + +: ${SSH_KEY_FILE?"Need to set SSH_KEY_FILE"} + +source bin/lib/aws_context +source bin/lib/conjur_context + +SEED_DIR="./tmp/conjur/seeds" + +function configure_master() { + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$MASTER_1_PUBLIC /bin/bash << EOF + docker exec conjur-appliance \ + evoke configure master \ + \$(docker exec conjur-appliance evoke configure master --help | grep -q accept-eula && echo "--accept-eula") \ + -h "$MASTER_1_PRIVATE" \ + --master-altnames "$LB_DNS,$MASTER_2_PRIVATE,$MASTER_3_PRIVATE" \ + -p "$CONJUR_ADMIN_PASSWORD" \ + "$CONJUR_ACCOUNT" + + docker exec conjur-appliance \ + evoke ca issue --force $LB_FOLLOWER_DNS +EOF +} + +function load_cluster_policy() { + mkdir -p ./tmp/conjur/policy + + cat > ./tmp/conjur/policy/conjur.yml < ./tmp/conjur/policy/cluster.yml < "/opt/conjur/backup/$filename" + " +EOF + + # Copy seed to host + scp -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "core@$MASTER_1_PUBLIC:/opt/conjur/backup/$filename" \ + "$SEED_DIR/$filename" +} + +function configure_standby() { + local standby_public=$1 + local filename=$2 + + # Copy seed + scp -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "$SEED_DIR/$filename" \ + "core@$standby_public:~/$filename" + + # Configure node + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$standby_public /bin/bash << EOF + sudo mv "\$HOME/$filename" "/opt/conjur/backup/$filename" + + docker exec conjur-appliance \ + evoke unpack seed "/opt/conjur/backup/$filename" + + docker exec conjur-appliance \ + evoke configure standby -a "$MASTER_1_PRIVATE" +EOF +} + +function enroll_standby() { + local standby_public=$1 + local standby_private=$2 + + # Configure node + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$standby_public /bin/bash << EOF + docker exec conjur-appliance \ + evoke cluster enroll \ + ${3:-} \ + -n "$standby_private" \ + -m "$MASTER_1_PRIVATE" \ + "$CONJUR_CLUSTER_NAME" +EOF +} + +function enable_sync_replication() { + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$MASTER_1_PUBLIC /bin/bash << EOF + docker exec conjur-appliance \ + evoke replication sync +EOF +} + +configure_master + +create_standby_seed $MASTER_2_PRIVATE "master-2-seed.tar" +configure_standby $MASTER_2_PUBLIC "master-2-seed.tar" + +create_standby_seed $MASTER_3_PRIVATE "master-3-seed.tar" +configure_standby $MASTER_3_PUBLIC "master-3-seed.tar" + +enable_sync_replication + +./bin/util/wait_for_master + +load_cluster_policy +enroll_master +enroll_standby $MASTER_2_PUBLIC $MASTER_2_PRIVATE +enroll_standby $MASTER_3_PUBLIC $MASTER_3_PRIVATE + +./bin/util/wait_for_master + +cat << EOF + +============================================== +Your HA Conjur Cluster is running at: + +https://${LB_DNS} + +Username: admin +Password value is in the file 'tmp/conjur/admin_password' +============================================== + +EOF diff --git a/demos/aws-cluster/2_kill_active_master b/demos/aws-cluster/2_kill_active_master new file mode 100755 index 00000000..3f1c46c9 --- /dev/null +++ b/demos/aws-cluster/2_kill_active_master @@ -0,0 +1,15 @@ +#!/bin/bash -eu + +# Provides ACTIVE_MASTER_NUM +source bin/lib/active_master + +# Kill the master +bin/util/kill_node $ACTIVE_MASTER_NUM + +mkdir -p ./tmp/script +echo $ACTIVE_MASTER_NUM > ./tmp/script/last_master_killed + +echo "Waiting for auto-failover..." + +# Wait for the cluster to recover +./bin/util/wait_for_master diff --git a/demos/aws-cluster/3_reenroll_failed_master b/demos/aws-cluster/3_reenroll_failed_master new file mode 100755 index 00000000..4ef3d8b3 --- /dev/null +++ b/demos/aws-cluster/3_reenroll_failed_master @@ -0,0 +1,13 @@ +#!/bin/bash -eu + +# Provides ACTIVE_MASTER_NUM +source bin/lib/active_master + +failed_node_num=$(<./tmp/script/last_master_killed) + +./bin/util/reenroll_node $failed_node_num $ACTIVE_MASTER_NUM + +echo "Waiting for master cluster..." + +# Wait for the cluster to recover +./bin/util/wait_for_master diff --git a/demos/aws-cluster/Dockerfile b/demos/aws-cluster/Dockerfile new file mode 100644 index 00000000..8875e273 --- /dev/null +++ b/demos/aws-cluster/Dockerfile @@ -0,0 +1,14 @@ +# Use the light version of the image that contains just the latest binary +FROM hashicorp/terraform:light + +# The app folder will contain all our files +WORKDIR /app + +# Put all your configration files in the same folder as the Dockerfile +COPY . /app + +# Initalize terraform with local settings and data +RUN ["terraform", "init"] + +# Plan and execute the configurations +CMD [ "apply"] diff --git a/demos/aws-cluster/README.md b/demos/aws-cluster/README.md new file mode 100644 index 00000000..9c24cb89 --- /dev/null +++ b/demos/aws-cluster/README.md @@ -0,0 +1,221 @@ +# Conjur HA in AWS + +## Introduction +This project demonstrates deploying and managing a HA Conjur cluster in AWS. +The architecture for this deployment is as follows: + +![Conjur AWS Architecture](images/Conjur-HA.png) + +### Load Balancer + +This demo uses an AWS Classic Load Balancer (LB) as the ingress point for +connections to the master cluster. The LB is responsible for performing +health checks against the three nodes to determine which one is active +and should receive traffic. + +The LB forwards three TCP ports to the active master cluster node: + +- 443: HTTPS traffic for API and UI interactions +- 5432: Follower data replication from the Master +- 1999: Follower audit log forward to the Master + +The LB is configured to expect a `200` HTTP response status code from a node's `/health` endpoint to be considered healthy. Standbys return a `502` status code, and will be considered unhealthy by the load balancer, preventing traffic from being directed to them. + +### EC2 Master Instances + +The master cluster nodes are all EC2 instances running the Conjur EE +AMI image. This demo uses `m4.large` instance types and the security groups +allow inbound connects on ports: + +- 443: HTTPS traffic +- 5432: Postgres traffic for follower replication +- 1999: Syslog traffic for follower audit log forwarding +- 22: SSH traffic for system administration + +## Prerequisites + +This demo requires the following tools to: + +- Docker +- Docker Compose +- Terraform +- AWS CLI + +## Deployment + +To initially install the cluster: + +1. Create a file in the project directory called `terraform.tfvars` and + configure the AWS environment for the deployment: + ```sh + # (OPTIONAL) Arbitrary prefix to add to each resource name + resource_prefix = "" + + # (REQUIRED) VPC to provision Load Balancer and Nodes into + vpc_id = "" + + # (REQUIRED) AMI to use for Conjur Master nodes + ami_id = "" + + # (REQUIRED) Name of SSH key pair to attach to Conjur Master nodes + key_name = "" + + # (OPTIONAL) Names of availability zones to use for nodes, + # defaults to the value below + availability_zones = ["us-east-1a", "us-east-1b"] + ``` + +2. Provision the AWS resources: + The terraform scripts assumes you will set the AWS connection credentials as environment variables as below: + ```sh + $ export AWS_ACCESS_KEY_ID="anaccesskey" + $ export AWS_SECRET_ACCESS_KEY="asecretkey" + $ export AWS_DEFAULT_REGION="us-west-2" + ``` + ```sh-session + $ ./0_terraform_aws + ... + ``` + + +2. Generate certificates for the Cluster + > TBD, for now the cluster will use self-generated certificates + +3. Initialize the Conjur Cluster + > This script requires you to first set the environment variable `SSH_KEY_FILE`. + > The value of this variable should be the path to the SSH private key to connect + > to the EC2 nodes. e.g. `/user/conjur/.ssh/id_rsa` + ```sh-session + $ ./1_init_cluster + ... + Waiting for master cluster... + Successful Health Checks: 0 + ... + Successful Health Checks: 8 + Successful Health Checks: 9 + Successful Health Checks: 10 + ``` + +4. (Optional) Deploy Followers in AWS + To also configure followers with the cluster, run the command: + ``` + $ ./1.1_init_followers + ``` + + +## HA Scenarios + +This demo environment allows to walk through 3 HA management scenarios with Conjur + +### Auto-Failover + +1. Kill the Master Node + > **NOTE:** This script ends when the auto-failover to a new active node is complete. + ```sh-session + $ ./2_kill_active_master + Killing node 1 (ec2-3-93-33-221.compute-1.amazonaws.com)... + Waiting for auto-failover... + Waiting for master cluster... + Successful Health Checks: 0 + ... + Successful Health Checks: 8 + Successful Health Checks: 9 + Successful Health Checks: 10 + ``` + +### Failed Node Re-Enrollment + +1. Clean State on Failed Instance + ```sh-session + $ ./3_reenroll_failed_master + Recreating Conjur appliance container on failed host... + ... + Configuring new appliance as standby... + ... + Enrolling the new standby into the existing master cluster... + ... + Waiting for master cluster... + ... + Successful Health Checks: 10 + ``` + +### Reboot Entire Cluster + +> **NOTE:** This was previously done entirely manually using the AWS EC2 Console + +1. Stop All Instances + > TBD + +2. Start Active Master + > TBD + +3. Start Standbys + > TBD + +## Cleanup + +1. Clean up the AWS resources + ```sh-session + $ ./100_cleanup_aws + ... + ``` + +## Utility Tools + +There are a few additional scripts available in `bin/util` to make inspecting +the system state easier. + +- **follow_node_logs** + Connects to a master node and streams the Conjur logs from the appliance on that node. + ```sh-session + $ bin/util/follow_node_logs {node_id} # Where `node_id` is `1`, `2`, or `3` + ``` + +- **kill_node** + Connects to a master node and kills the Conjur appliance running on it + ```sh-session + $ bin/util/kill_node {node_id} # Where `node_id` is `1`, `2`, or `3` + ``` + +- **recreate_cluster** + Destroys and recreates all of the EC2 instances running the Conjur cluster + > **NOTE:** This is a destructive operation and requires rebuilding the Conjur cluster from scratch + ```sh-session + $ bin/util/recreate_cluster + ``` + +- **reenroll_node** + Rebuilds an appliance node as a standby and enrolls it into the Conjur master cluster + ```sh-session + $ bin/util/reenroll_node {standby_node_id} {master_node_id} # Where `node_id` is `1`, `2`, or `3` + ``` + +- **refresh_aws_state** + Refreshes the local state of the AWS resources + > **NOTE:** This allows the scripts to operate correctly after making changes (e.g. restarting) + > in the AWS web consol + ``` + $ bin/util/refresh_aws_state + ``` + +- **ssh_node** + Connects to a master node and begins a shell session on it + ```sh-session + $ bin/util/ssh_node {node_id} # Where `node_id` is `1`, `2`, or `3` + ``` + +- **wait_for_master** + Blocks the current shell session until the Conjur cluster is healthy + ```sh-session + $ bin/util/wait_for_master + ``` +- **watch_cluster_health** + Reports the health status of the Conjur cluster through the load balancer + ```sh-session + $ bin/util/watch_cluster_health + ``` +- **watch_node_health** + Reports the health status for a particular node of the Conjur cluster + ```sh-session + $ bin/util/watch_node_health # Where `node_id` is `1`, `2`, or `3` + ``` diff --git a/demos/aws-cluster/bin/lib/active_master b/demos/aws-cluster/bin/lib/active_master new file mode 100644 index 00000000..ff4a6c09 --- /dev/null +++ b/demos/aws-cluster/bin/lib/active_master @@ -0,0 +1,11 @@ +#!/bin/bash -eu + +source bin/lib/aws_context +source bin/lib/conjur_context + +info_response=$(curl -ks "https://$LB_DNS/info") + +export ACTIVE_MASTER_PRIVATE_DNS=$(echo $info_response | jq -r '.configuration.conjur.hostname') + +private_node_dns_list=$(terraform output -json conjur_master_nodes_private) +export ACTIVE_MASTER_NUM=$(echo $private_node_dns_list | jq ". | index(\"$ACTIVE_MASTER_PRIVATE_DNS\") + 1") diff --git a/demos/aws-cluster/bin/lib/aws_context b/demos/aws-cluster/bin/lib/aws_context new file mode 100644 index 00000000..4b5cb949 --- /dev/null +++ b/demos/aws-cluster/bin/lib/aws_context @@ -0,0 +1,19 @@ +#!/bin/bash -eu + +export LB_DNS_DEFAULT=$(terraform output conjur_master_lb_public) +export LB_DNS="${LB_DNS:-${LB_DNS_DEFAULT}}" + +export LB_FOLLOWER_DNS_DEFAULT=$(terraform output conjur_follower_lb_public) +export LB_FOLLOWER_DNS="${LB_FOLLOWER_DNS:-${LB_FOLLOWER_DNS_DEFAULT}}" + +export MASTER_1_PRIVATE=$(terraform output -json conjur_master_nodes_private | jq -r '.[0]') +export MASTER_1_PUBLIC=$(terraform output -json conjur_master_nodes_public | jq -r '.[0]') + +export MASTER_2_PRIVATE=$(terraform output -json conjur_master_nodes_private | jq -r '.[1]') +export MASTER_2_PUBLIC=$(terraform output -json conjur_master_nodes_public | jq -r '.[1]') + +export MASTER_3_PRIVATE=$(terraform output -json conjur_master_nodes_private | jq -r '.[2]') +export MASTER_3_PUBLIC=$(terraform output -json conjur_master_nodes_public | jq -r '.[2]') + +# Follower public DNS address, 1 per line +export FOLLOWERS_PUBLIC=$(terraform output -json conjur_follower_nodes_public | jq -r '.[]') diff --git a/demos/aws-cluster/bin/lib/conjur_context b/demos/aws-cluster/bin/lib/conjur_context new file mode 100644 index 00000000..509ce970 --- /dev/null +++ b/demos/aws-cluster/bin/lib/conjur_context @@ -0,0 +1,14 @@ +#!/bin/bash -eu + +# Generate admin password if it doesn't exist +CONJUR_PASSWORD_FILE="./tmp/conjur/admin_password" +if [ ! -f "$CONJUR_PASSWORD_FILE" ]; then + echo "Generating Conjur Password..." + mkdir -p "$(dirname "$CONJUR_PASSWORD_FILE")" + openssl rand -base64 32 > "$CONJUR_PASSWORD_FILE" +fi + +export CONJUR_ADMIN_PASSWORD=$(<"$CONJUR_PASSWORD_FILE") + +export CONJUR_ACCOUNT="${CONJUR_ACCOUNT:-conjur}" +export CONJUR_CLUSTER_NAME="${CONJUR_CLUSTER_NAME:-master}" diff --git a/demos/aws-cluster/bin/setup b/demos/aws-cluster/bin/setup new file mode 100755 index 00000000..cee4aa6b --- /dev/null +++ b/demos/aws-cluster/bin/setup @@ -0,0 +1,19 @@ +#!/bin/bash -eux + +# docker build -t terraform . + +mkdir -p ./tmp/terraform + +docker run --rm -it -v $(pwd):/app --entrypoint /bin/bash terraform +docker run --rm -it -v $(pwd):/app terraform plan -out=./tmp/terraform/conjur-ha.plan +# docker run --rm -it -v $(pwd):/app terraform init + +# # Generate the terraform execution plan +# terraform plan -out=./tmp/terraform/conjur-ha.plan +# +# # Execute the plan to create the AWS resources +# terraform apply ./tmp/terraform/conjur-ha.plan + + + +docker run -i --workdir /src -v "$(pwd):/src" hashicorp/terraform:light --help diff --git a/demos/aws-cluster/bin/util/follow_node_logs b/demos/aws-cluster/bin/util/follow_node_logs new file mode 100755 index 00000000..99f9bfb7 --- /dev/null +++ b/demos/aws-cluster/bin/util/follow_node_logs @@ -0,0 +1,11 @@ +#!/bin/bash -eu + +node_num=$1 +node_index=$((node_num - 1)) + +public_dns=$(terraform output -json conjur_master_nodes_public | jq -r ".[$node_index]") + + +ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "core@$public_dns" "docker logs conjur-appliance --follow" diff --git a/demos/aws-cluster/bin/util/kill_node b/demos/aws-cluster/bin/util/kill_node new file mode 100755 index 00000000..ca5cfdf0 --- /dev/null +++ b/demos/aws-cluster/bin/util/kill_node @@ -0,0 +1,12 @@ +#!/bin/bash -eu + +node_num=$1 +node_index=$((node_num - 1)) + +public_dns=$(terraform output -json conjur_master_nodes_public | jq -r ".[$node_index]") + +echo "Killing node $node_num ($public_dns)..." + +ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "core@$public_dns" docker kill conjur-appliance > /dev/null diff --git a/demos/aws-cluster/bin/util/recreate_cluster b/demos/aws-cluster/bin/util/recreate_cluster new file mode 100755 index 00000000..b396780f --- /dev/null +++ b/demos/aws-cluster/bin/util/recreate_cluster @@ -0,0 +1,4 @@ +#!/bin/bash -eu + +terraform destroy -auto-approve -target=aws_instance.conjur_master_node +terraform apply -auto-approve -target=aws_instance.conjur_master_node diff --git a/demos/aws-cluster/bin/util/reenroll_node b/demos/aws-cluster/bin/util/reenroll_node new file mode 100755 index 00000000..1fac522f --- /dev/null +++ b/demos/aws-cluster/bin/util/reenroll_node @@ -0,0 +1,120 @@ +#!/bin/bash -eu + +source bin/lib/conjur_context + +DROPPED_NODE_ID=$1 +NEW_MASTER_ID=$2 + +DROPPED_NODE_INDEX=$((DROPPED_NODE_ID - 1)) +NEW_MASTER_INDEX=$((NEW_MASTER_ID - 1)) + +MASTER_PRIVATE=$(terraform output -json conjur_master_nodes_private | jq -r ".[$NEW_MASTER_INDEX]") +MASTER_PUBLIC=$(terraform output -json conjur_master_nodes_public | jq -r ".[$NEW_MASTER_INDEX]") + +STANDBY_PRIVATE=$(terraform output -json conjur_master_nodes_private | jq -r ".[$DROPPED_NODE_INDEX]") +STANDBY_PUBLIC=$(terraform output -json conjur_master_nodes_public | jq -r ".[$DROPPED_NODE_INDEX]") + +SEED_DIR="./tmp/conjur/seeds" + +current_master=$MASTER_PUBLIC + +function recreate_standby() { + local standby_public=$1 + local standby_private=$2 + + # Configure node + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$standby_public /bin/bash << EOF + + docker stop conjur-appliance + docker rm conjur-appliance + + docker run --name conjur-appliance \ + -d --restart=always --privileged \ + --log-driver=journald \ + -v /var/log/conjur:/var/log/conjur \ + -v /opt/conjur/backup:/opt/conjur/backup \ + -p "443:443" -p "636:636" -p "5432:5432" -p "1999:1999" \ + registry.tld/conjur-appliance:11.4.0 +EOF +} + +function create_standby_seed() { + local standby_private=$1 + local filename=$2 + + mkdir -p $SEED_DIR + + # Create Standby Seed + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$current_master /bin/bash << EOF + docker exec conjur-appliance bash -c " \ + evoke seed standby "$standby_private" "$MASTER_PRIVATE" > "/opt/conjur/backup/$filename" + " +EOF + + # Copy seed to host + scp -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "core@$current_master:/opt/conjur/backup/$filename" \ + "$SEED_DIR/$filename" +} + +function configure_standby() { + local standby_public=$1 + local filename=$2 + + # Copy seed + scp -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "$SEED_DIR/$filename" \ + "core@$standby_public:~/$filename" + + # Configure node + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$standby_public /bin/bash << EOF + sudo mv "\$HOME/$filename" "/opt/conjur/backup/$filename" + + docker exec conjur-appliance \ + evoke unpack seed "/opt/conjur/backup/$filename" + + docker exec conjur-appliance \ + evoke configure standby -a "$MASTER_PRIVATE" +EOF +} + +function add_cluster_member() { + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$MASTER_PUBLIC /bin/bash << EOF + docker exec conjur-appliance \ + evoke cluster member add $STANDBY_PRIVATE +EOF +} + +function reenroll_node() { + ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + core@$STANDBY_PUBLIC /bin/bash << EOF + docker exec conjur-appliance \ + evoke cluster enroll \ + --reenroll \ + -n $STANDBY_PRIVATE \ + -m $MASTER_PRIVATE \ + $CONJUR_CLUSTER_NAME +EOF +} + +echo "Recreating Conjur appliance container on failed host..." +recreate_standby $STANDBY_PUBLIC $STANDBY_PRIVATE + +echo "Configuring new appliance as standby..." +create_standby_seed $STANDBY_PRIVATE "master-${DROPPED_NODE_ID}-seed.tar" +configure_standby $STANDBY_PUBLIC "master-${DROPPED_NODE_ID}-seed.tar" + +echo "Enrolling the new standby into the existing master cluster..." +add_cluster_member +reenroll_node diff --git a/demos/aws-cluster/bin/util/refresh_aws_state b/demos/aws-cluster/bin/util/refresh_aws_state new file mode 100755 index 00000000..eeb8b10c --- /dev/null +++ b/demos/aws-cluster/bin/util/refresh_aws_state @@ -0,0 +1,3 @@ +#!/bin/bash -eu + +terraform refresh diff --git a/demos/aws-cluster/bin/util/ssh_node b/demos/aws-cluster/bin/util/ssh_node new file mode 100755 index 00000000..24ffc620 --- /dev/null +++ b/demos/aws-cluster/bin/util/ssh_node @@ -0,0 +1,12 @@ +#!/bin/bash -eu + +node_num=$1; shift +node_index=$((node_num - 1)) + +public_dns=$(terraform output -json conjur_master_nodes_public | jq -r ".[$node_index]") + +echo "Connecting to node $node_num ($public_dns)..." + +ssh -i "$SSH_KEY_FILE" \ + -o "StrictHostKeyChecking no" \ + "core@$public_dns" "$@" diff --git a/demos/aws-cluster/bin/util/wait_for_master b/demos/aws-cluster/bin/util/wait_for_master new file mode 100755 index 00000000..109820fd --- /dev/null +++ b/demos/aws-cluster/bin/util/wait_for_master @@ -0,0 +1,17 @@ +#!/bin/bash -eu + +source bin/lib/aws_context + +echo "Waiting for master cluster..." +# Wait for 10 successful connections in a row +COUNTER=0 +while [ $COUNTER -lt 10 ]; do + if [ -z "$(curl -k --silent --head https://$LB_DNS/health | grep "Conjur-Health: OK")" ]; then + sleep 5 + COUNTER=0 + else + let COUNTER=COUNTER+1 + fi + sleep 1 + echo "Successful Health Checks: $COUNTER" +done diff --git a/demos/aws-cluster/bin/util/watch_cluster_health b/demos/aws-cluster/bin/util/watch_cluster_health new file mode 100755 index 00000000..8379863f --- /dev/null +++ b/demos/aws-cluster/bin/util/watch_cluster_health @@ -0,0 +1,7 @@ +#!/bin/bash -eu + +source bin/lib/aws_context + +watch -n 2 \ + curl -k --silent --head --fail \ + https://$LB_DNS/health diff --git a/demos/aws-cluster/bin/util/watch_node_health b/demos/aws-cluster/bin/util/watch_node_health new file mode 100755 index 00000000..c97a796e --- /dev/null +++ b/demos/aws-cluster/bin/util/watch_node_health @@ -0,0 +1,10 @@ +#!/bin/bash -eu + +node_num=$1 +node_index=$((node_num - 1)) + +public_dns=$(terraform output -json conjur_master_nodes_public | jq -r ".[$node_index]") + +watch -n 2 \ + curl -k --silent --head --fail \ + https://$public_dns/health diff --git a/demos/aws-cluster/docker-compose.yml b/demos/aws-cluster/docker-compose.yml new file mode 100644 index 00000000..18575b72 --- /dev/null +++ b/demos/aws-cluster/docker-compose.yml @@ -0,0 +1,8 @@ +version: "3" +services: + cli: + image: cyberark/conjur-cli:5 + entrypoint: bash + volumes: + - ./tmp/cli:/root + - ./tmp/conjur:/data diff --git a/demos/aws-cluster/images/Conjur-HA.png b/demos/aws-cluster/images/Conjur-HA.png new file mode 100644 index 00000000..5a8ccaca Binary files /dev/null and b/demos/aws-cluster/images/Conjur-HA.png differ diff --git a/demos/aws-cluster/images/Conjur-HA.xml b/demos/aws-cluster/images/Conjur-HA.xml new file mode 100644 index 00000000..c3e2f8d6 --- /dev/null +++ b/demos/aws-cluster/images/Conjur-HA.xml @@ -0,0 +1 @@ +7Vpbb+MoFP41kXYfWnGJ7fixTdu9qJW6G2l2tS8VsanDDjYRJkmzv37BxoltcNuZSSedKr2aAxzw+b7zgYlHeJo//SLJcnEnUspHCKRPI3w1QigOgP5rDNvaEOK4NmSSpbUJ7g0z9h+1RtsvW7GUlp2GSgiu2LJrTERR0ER1bERKsek2exS8O+qSZNQxzBLCXetfLFULa4UA7Ct+pSxb2KEnzQ3PSfI5k2JV2PFGCD9WX3V1Thpftn25IKnYtEz4eoSnUghVX+VPU8pNaJuw1f1uBmp385a0UK/pwP9cbcv7cvaH/HsJ1ptQpb/fnUFUu1kTvrIBuVgTxsmccaa2uuYfUVD978LehNo2gVsKVqgq+MGl/tGDT8Eo0DVTUzpHQc/QL0ddA3RLxkfX0C9HXQPsu4e98WF/gi2DU+q4B73xQWuC+gdfipXirKDTHU2BNmaSpEzjMxVcSG0rTDDx5ULlXJegvtwsmKKzJUlMVDc6w7TtURTKJorGx5Zt4I1XzaSluc6fMpOS52RTjs8NFZfVkL/pVPHWPpSreUGV8aCk+EybWWnmTqIYxqEZi3Hem+2aSsV0wlxwlhnHSphxiC1x+lh51LfAiuy2Kl1hYKftGyIl5YKm9l4s/fQQ9GmQ2HCXLlqFqMipkoaatgOOAwOu6WQ1CEY25zb7jEah1aVFK5khtg2JVZFs532fSfrCJpM/scIURkEUpyCO4jFEk7Oxk1NO8lS6UQXBkIDIxOI97sfHQQpUX36kBuhW+2jUDdUMqrXIOEpEzhJ7bTC7ITnjJpKfqExJQQYY6ZtTi9gDKHqwHgQWxqgLK544sAZg4sKKMXoDWOOvhxWCNq7wQLgah/dEKSpNIuo4AKx/YfX/x0UdT0AX9SB0UMfN6txBHYzfAPXd8r1HmaZ6B2GLQqqFyERB+PXeernnQS8+emGl/HK3c3g2UeHrkRkMeylWMqEDt2bbmNt5FhhJOVFs3d0w+YJcdb2QkmxbDew+Ye/53hhaWR518Xb2MS+1j+MewPUM/L1R4O+9m64iMqPK9urxZheTr6NSkwrPCEhH+1u88Sz5+DzXZMhorjF/0Et+KSrqteVDJ+kVutLL8bCGdBVrUCEcuboOzbfD2fDb1eQAEtJXkAg1G4SWhoTYlZDGdlgFgQ7MH0VB0PtQkPBZRfjS9u9YQdyntZOCfA8FQUdWEBfmj6Ig+H0oSG9PMbYPEB9vD4JPCnIUBcHHVZDgwLAnXKxSF+mbYBLg8Pkn1t0YHxL23bl2s/dE7lFUgFzUcfgW6wb+kdeNA68JjgxjBHrnho4Q10uXI8Suq/5+4e0U3XuM76q6FuN/V/IsJ6Wi0jx5htwc086lvsrM1U93VdXPbo3P0mOR97C7k9zNofGtIc29KJli1an0XCgl8hdPlRNNBipfIUSsKBUpEs+qU2nReFiLBjL7S06e9TahzyDgpnvoOas6hMh7meAK/ZSTstRqisCtIKkLro65CaD0UGQ8xubTDgSCakNkrmAcx17OvFuGkOWSazfG+wPXEXiYNzd8DMo4e79w7BLG80lFdIATbS9hohekA3l4MdsWhk8znXnpfHuSkG/gQxBE3f1Cs3IcS0AmL/ABe/hwUZ4IcbA1JY56awrG0Pfo8D1JAd2ja/9rAi6sp9cETq8JjN7HawK4m1bA/TT5YC8J6OL+zZ56l79/ewpf/w8= \ No newline at end of file diff --git a/demos/aws-cluster/main.tf b/demos/aws-cluster/main.tf new file mode 100644 index 00000000..b7757128 --- /dev/null +++ b/demos/aws-cluster/main.tf @@ -0,0 +1,298 @@ +############################################# +# Inputs +############################################# + +variable "vpc_id" { + type = string +} + +variable "ami_id" { + type = string +} + +variable "key_name" { + type = string +} + +variable "availability_zones" { + default = ["us-east-1a", "us-east-1b"] +} + +variable "resource_prefix" { + type = string + default = "" +} + +############################################# +# Configure the AWS Provider +############################################# + +provider "aws" {} + +############################################# +# State Information from AWS +############################################# + +data "aws_subnet" "subnet" { + count = length(var.availability_zones) + + vpc_id = var.vpc_id + availability_zone = element(var.availability_zones, count.index) +} + + +############################################# +# Load Balancer Config +############################################# + +resource "aws_security_group" "lb" { + name = "${var.resource_prefix}conjur-ha-lb" + description = "Allow Conjur Master Traffic" + vpc_id = var.vpc_id + + ingress { + from_port = 443 + to_port = 443 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 5432 + to_port = 5432 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 1999 + to_port = 1999 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +# Load balancer for master cluster +resource "aws_elb" "lb" { + name = "${var.resource_prefix}conjur-ha-lb" + + subnets = data.aws_subnet.subnet.*.id + security_groups = [aws_security_group.lb.id] + + # API and UI + listener { + instance_port = 443 + instance_protocol = "tcp" + lb_port = 443 + lb_protocol = "tcp" + } + + # Postgres Replication + listener { + instance_port = 5432 + instance_protocol = "tcp" + lb_port = 5432 + lb_protocol = "tcp" + } + + # Syslog Forwarding + listener { + instance_port = 1999 + instance_protocol = "tcp" + lb_port = 1999 + lb_protocol = "tcp" + } + + health_check { + healthy_threshold = 2 + unhealthy_threshold = 2 + timeout = 3 + target = "HTTPS:443/health" + interval = 30 + } + + tags = { + Name = "${var.resource_prefix}conjur-ha-lb" + } +} + +# Load balancer for followers +resource "aws_elb" "follower_lb" { + name = "${var.resource_prefix}conjur-ha-follower-lb" + + subnets = data.aws_subnet.subnet.*.id + security_groups = [aws_security_group.lb.id] + + # API and UI + listener { + instance_port = 443 + instance_protocol = "tcp" + lb_port = 443 + lb_protocol = "tcp" + } + + health_check { + healthy_threshold = 2 + unhealthy_threshold = 2 + timeout = 3 + target = "HTTPS:443/health" + interval = 30 + } + + tags = { + Name = "${var.resource_prefix}conjur-ha-follower-lb" + } +} + +############################################# +# 3-Node Master Cluster Config +############################################# + +# Security Group for Node Instances +resource "aws_security_group" "master_node" { + name = "${var.resource_prefix}conjur-ha-master-node" + description = "Allow Conjur Master Node Traffic" + vpc_id = var.vpc_id + + ingress { + from_port = 443 + to_port = 443 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 5432 + to_port = 5432 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 1999 + to_port = 1999 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 22 + to_port = 22 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +# Instances +resource "aws_instance" "conjur_master_node" { + count = 3 + + ami = var.ami_id + instance_type = "m4.large" + availability_zone = element(var.availability_zones, count.index) + subnet_id = element(data.aws_subnet.subnet.*.id, count.index) + key_name = var.key_name + vpc_security_group_ids = [aws_security_group.master_node.id] + + tags = { + Name = "${var.resource_prefix}conjur-master-${count.index + 1}" + } +} + +resource "aws_elb_attachment" "lb_nodes" { + count = length(aws_instance.conjur_master_node) + elb = aws_elb.lb.id + instance = element(aws_instance.conjur_master_node.*.id, count.index) +} + +############################################# +# Follower config +############################################# + +# Security Group for Node Instances +resource "aws_security_group" "follower_node" { + name = "${var.resource_prefix}conjur-ha-follower-node" + description = "Allow Conjur Follower Node Traffic" + vpc_id = var.vpc_id + + ingress { + from_port = 443 + to_port = 443 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 22 + to_port = 22 + protocol = "6" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +# Instances +resource "aws_instance" "conjur_follower_node" { + count = 2 + + ami = var.ami_id + instance_type = "m4.large" + availability_zone = element(var.availability_zones, count.index) + subnet_id = element(data.aws_subnet.subnet.*.id, count.index) + key_name = var.key_name + vpc_security_group_ids = [aws_security_group.follower_node.id] + + tags = { + Name = "${var.resource_prefix}conjur-follower-${count.index + 1}" + } +} + +resource "aws_elb_attachment" "follower_lb_nodes" { + count = length(aws_instance.conjur_follower_node) + elb = aws_elb.follower_lb.id + instance = element(aws_instance.conjur_follower_node.*.id, count.index) +} + +############################################# +# Outputs +############################################# + +output "conjur_master_lb_public" { + value = aws_elb.lb.dns_name +} + +output "conjur_follower_lb_public" { + value = aws_elb.follower_lb.dns_name +} + +output "conjur_master_nodes_public" { + value = aws_instance.conjur_master_node.*.public_dns +} + +output "conjur_master_nodes_private" { + value = aws_instance.conjur_master_node.*.private_dns +} + +output "conjur_follower_nodes_public" { + value = aws_instance.conjur_follower_node.*.public_dns +} \ No newline at end of file diff --git a/demos/aws-cluster/terraform.tfvars-sample b/demos/aws-cluster/terraform.tfvars-sample new file mode 100644 index 00000000..cc65c8d2 --- /dev/null +++ b/demos/aws-cluster/terraform.tfvars-sample @@ -0,0 +1,14 @@ +# (REQUIRED) VPC to provision Load Balancer and Nodes into +vpc_id = "" + +# (REQUIRED) AMI to use for Conjur Master nodes +ami_id = "" + +# (REQUIRED) Name of SSH key pair to attach to Conjur Master nodes +key_name = "" + +# (OPTIONAL) Names of availability zones to use for nodes, +# defaults to the value below +# availability_zones = ["us-east-1a", "us-east-1b"] + +resource_prefix = "" diff --git a/demos/certificate-authority/mutual-tls/.gitignore b/demos/certificate-authority/mutual-tls/.gitignore new file mode 100644 index 00000000..0b998ec7 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/.gitignore @@ -0,0 +1,22 @@ +conjur/data_key +conjur/admin_info +cli/cache/.conjurrc +cli/cache/.bash_history +cli/cache/.netrc +cli/host_logins +ca/ca/root.srl +ca/ca/root.key +ca/ca/root.crt +ca/ca/intermediate.key +ca/ca/intermediate.csr +ca/ca/intermediate.crt +ca/ca/ca-chain.crt +ca/.rnd +client/ca-chain.crt +client/client.crt +client/client.csr +client/client.key +server/ca-chain.crt +server/server.crt +server/server.csr +server/server.key \ No newline at end of file diff --git a/demos/certificate-authority/mutual-tls/0_start b/demos/certificate-authority/mutual-tls/0_start new file mode 100755 index 00000000..604ef973 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/0_start @@ -0,0 +1,26 @@ +#!/bin/bash -eu + +echo "Pulling latest images..." +docker-compose pull > /dev/null 2>&1 +docker-compose build > /dev/null 2>&1 + +# Generate Conjur data key if it doesn't exist +if [ ! -f conjur/data_key ]; then + echo "Generating Conjur data key..." + docker-compose run --no-deps -T --rm conjur data-key generate > conjur/data_key +fi + +echo "Starting Conjur..." +export CONJUR_DATA_KEY="$(< conjur/data_key)" +docker-compose up -d conjur > /dev/null 2>&1 + +# Wait for Conjur to be ready +docker-compose exec conjur conjurctl wait + +# Create cucumber account and admin role +docker-compose exec -T conjur conjurctl account create cucumber > conjur/admin_info + +admin_secret=$(cat conjur/admin_info | sed -n -e 's/^.*API key for admin: //p') +echo "------------------------------" +echo "Admin secret is: $admin_secret" +echo "------------------------------" diff --git a/demos/certificate-authority/mutual-tls/1_load_policy b/demos/certificate-authority/mutual-tls/1_load_policy new file mode 100755 index 00000000..4844745c --- /dev/null +++ b/demos/certificate-authority/mutual-tls/1_load_policy @@ -0,0 +1,14 @@ +#!/bin/bash -eu + +docker-compose run --rm cli -c "conjur init --force=true -u \$CONJUR_APPLIANCE_URL -a \$CONJUR_ACCOUNT" +docker-compose run --rm cli -c "conjur authn login -u \$CONJUR_AUTHN_LOGIN" +host_logins=$(docker-compose run --rm -T cli -c "conjur policy load root /src/cli/mutual_tls.yml") +echo "$host_logins" > cli/host_logins + +server_password=$(cat cli/host_logins | jq -r '.created_roles | .["cucumber:host:mutual-tls/server"] | .api_key') +client_password=$(cat cli/host_logins | jq -r '.created_roles | .["cucumber:host:mutual-tls/client"] | .api_key') + +echo "-------------------------------------------" +echo "Server password: $server_password" +echo "Client password: $client_password" +echo "-------------------------------------------" diff --git a/demos/certificate-authority/mutual-tls/2_create_ca b/demos/certificate-authority/mutual-tls/2_create_ca new file mode 100755 index 00000000..925864d0 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/2_create_ca @@ -0,0 +1,23 @@ +#!/bin/bash -eu + +# Generate root and intermediate CA certificates + +if [ ! -d ca/ca ]; then + docker-compose run --rm --user $(id -u) ca +fi + +auth_header=$(docker-compose run --rm -T cli -c 'conjur authn authenticate -H') + +echo Store the intermediate CA private key in Conjur... +curl --data-binary "@ca/ca/intermediate.key" \ + -H "$auth_header" \ + "http://localhost:8080/secrets/cucumber/variable/conjur/mutual-tls/ca/private-key" + +echo Store the intermediate certificate chain in Conjur... +curl --data-binary "@ca/ca/ca-chain.crt" \ + -H "$auth_header" \ + "http://localhost:8080/secrets/cucumber/variable/conjur/mutual-tls/ca/cert-chain" + +rm -rf server/ca-chain.crt client/ca-chain.crt +cp ca/ca/ca-chain.crt server/ca-chain.crt +cp ca/ca/ca-chain.crt client/ca-chain.crt diff --git a/demos/certificate-authority/mutual-tls/3_create_server_cert b/demos/certificate-authority/mutual-tls/3_create_server_cert new file mode 100755 index 00000000..00d8ffed --- /dev/null +++ b/demos/certificate-authority/mutual-tls/3_create_server_cert @@ -0,0 +1,5 @@ +#!/bin/bash -eu + +rm -rf server/server.crt +docker-compose run --rm --user $(id -u) server /server/request_certificate +chmod 444 server/server.crt diff --git a/demos/certificate-authority/mutual-tls/4_create_client_cert b/demos/certificate-authority/mutual-tls/4_create_client_cert new file mode 100755 index 00000000..60c36223 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/4_create_client_cert @@ -0,0 +1,5 @@ +#!/bin/bash -eu + +rm -rf client/client.crt +docker-compose run --rm --user $(id -u) client /client/request_certificate +chmod 444 client/client.crt diff --git a/demos/certificate-authority/mutual-tls/5_connect b/demos/certificate-authority/mutual-tls/5_connect new file mode 100755 index 00000000..b3d27fa9 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/5_connect @@ -0,0 +1,30 @@ +#!/bin/bash -e + +# Determine which extra services should be loaded when working with authenticators +INCLUDE_CERT_CHAIN=false +INCLUDE_CLIENT_CERT=false +while true ; do + case "$1" in + --ca-chain ) INCLUDE_CERT_CHAIN=true ; shift ;; + --client-cert ) INCLUDE_CLIENT_CERT=true ; shift ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac +done + +echo "Starting server..." +docker-compose rm -fs server > /dev/null 2>&1 +docker-compose build server > /dev/null 2>&1 +docker-compose up -d server > /dev/null 2>&1 + +args="" + +if [[ $INCLUDE_CERT_CHAIN = true ]]; then + args="$args --cacert /client/ca-chain.crt" +fi + +if [[ $INCLUDE_CLIENT_CERT = true ]]; then + args="$args --cert /client/client.crt --key /client/client.key" +fi + +echo "Connecting client (Certificate Chain=$INCLUDE_CERT_CHAIN, Client Certificate=$INCLUDE_CLIENT_CERT)..." +docker-compose run --rm client bash -c "curl $args https://server" || true diff --git a/demos/certificate-authority/mutual-tls/6_stop b/demos/certificate-authority/mutual-tls/6_stop new file mode 100755 index 00000000..c2b8b79c --- /dev/null +++ b/demos/certificate-authority/mutual-tls/6_stop @@ -0,0 +1,4 @@ +#!/bin/bash -eu + +docker-compose down +docker-compose rm diff --git a/demos/certificate-authority/mutual-tls/README.md b/demos/certificate-authority/mutual-tls/README.md new file mode 100644 index 00000000..4b568c04 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/README.md @@ -0,0 +1,140 @@ +# Mutual TLS with Conjur + +This example demonstrates using Conjur as certificate authority (CA) to configure +two hosts with X.509 certificates for mutual TLS authentication. The hosts +used for this example are an nginx web server and a cUrl web client. + +The Conjur CA is configured in policy and uses an intermediate CA certificate +and private key created using OpenSSL and stored in Conjur variables. + +With the CA configured, each host is able to authenticate to Conjur using +its own identity, and submit an X.509 certificate signing request (CSR) +to the CA to have it signed using the intermediate CA private key. + +With the host certificates issues, each host is able to authenticate to the +other using mutual TLS. + +### Prerequisites + +1. docker +2. docker-compose + +### Getting Started + +1. Start the environment to pull and start the container images + ```sh-session + $ ./0_start + Pulling latest images... + Starting Conjur... + Waiting for Conjur to be ready... + ....... Conjur is ready! + Created new account account 'cucumber' + ------------------------------ + Admin secret is: 32s6txpth3nc7ejkded2t8mexe209ccq3newxgs60emq5vk5dkb + ------------------------------ + ``` + +2. Load the policy to configure the CA, host identities, and privileges + ```sh-session + $ ./1_load_policy + Wrote configuration to /root/.conjurrc + Please enter admin's password (it will not be echoed): # use password from prior command + Logged in + Loaded policy 'root' + ------------------------------------------- + Server password: 2tm5age3akt70w14aqz4z1p9mvn61qzeybm2x9w8gc22ev8nq36g4xmm + Client password: 1s8b2pf1g5as48836jgsxjftpb2rzbdh80f3gse8vz8n30ne0qv + ------------------------------------------- + ``` + +3. Create the root and intermediate CA certificates, and load the intermediate + CA certificate and key into Conjur + ```sh-session + $ ./2_create_ca + Store the intermediate CA private key in Conjur... + Store the intermediate certificate chain in Conjur... + ``` + +4. Log the web server host into Conjur and request a host certificate from the + Conjur CA + ```sh-session + $ ./3_create_server_cert + Password for mutual-tls/server: # server password from above + -----BEGIN CERTIFICATE----- + MIIEWzCCAkOgAwIBAgIUB71ZMj8EcCOt9xtEIINh3mEvsiEwDQYJKoZIhvcNAQEL + BQAwUjELMAkGA1UEBhMCVVMxCjAIBgNVBAgMAS4xCjAIBgNVBAcMAS4xCjAIBgNV + BAoMAS4xHzAdBgNVBAMMFkNvbmp1ciBJbnRlcm1lZGlhdGUgQ0EwHhcNMTgwODIy + MTkxNzA2WhcNMTgwODIzMTkxNzA2WjBCMQswCQYDVQQGEwJVUzEKMAgGA1UECAwB + LjEKMAgGA1UEBwwBLjEKMAgGA1UECgwBLjEPMA0GA1UEAwwGc2VydmVyMIIBIjAN + BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAny/4YqlgwhVZSjOX2Nj+SV32i30c + Wu5+MmrREJhIMTJgkdwEpS9nXyheDSAGsO0DI105HQ8uRiNVkFYgZ/i02wbZ09SW + imtVbj73NjyeEUFNPKn9zwDOy4wwXbPjOWWlHUsxVNclzYD7RnhNht37iZvbTEyG + NPvf90w76vdJyuxxQo01jZ9oe1b4SLrzMXEIShX/V25aJeIC54upiuqOAeC+QwV4 + Tb7tNWcJyWIwSaM7Q87t5s0IGbd4zlrRTBxyHRmqazBbdndnOyPQkz9P4sb2IHey + vcKiGCZYI8CzpWm6S/29xBkq39/RoE5DUmWuVQi9YQGfJT17BnHgE5RUcQIDAQAB + ozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUsx4h40TWHyMK + qGE584dtidlxk2EwDQYJKoZIhvcNAQELBQADggIBAHHoyXzMybjt3miV7JM2qVEA + wXeB/C6Wo505N2oPYUn+b+iobbWmv1YQ6mXUpZInMDSZBEs0lXMExn3VHRWFrYVt + Vwp7rRCdqwXSV1ltOHo3yy0AhY7HQj2i5NUVM2ewLtNRqx8Yq8MW+C0gHpoV/c2h + 3nGxgOxKzjGjd8xYc7TNnVAuZ7kLxp2EtoAIGVnPbW+afJCNAcSdAWBiKfJL1+Va + gEc3Ot8WGECGBGD4qUO12woGmTNqexEirr4JnKBmh/ug+1sH5nukiUnFFINBpxrN + 4h7CLsGDMEXcCzqUDJgqNtWGnMHbrRA8Mj0t5xj//Sbs7iodSuu0TMNy/9spRyfd + R51QuA91Hw5iZiVj0qWVPmoGyjb5UpCoT261qf3tG9+FqxfzW8oltHOH2ev4nnqC + 3ohuLBB/yfutK17mr8LBPMc+uELaTHMDWAPDO0hY+zFANM47ALrvG9NIAkKhQh9w + eHMTwtbSNlOgPvE8FTixpcDwN61lanvyCtXyZ4ET4JwVFXZqN8VtDs9RG9z0api6 + fG1jLsSEyha8Cec6bYLhLZ9MCwo3nkopT6qABQYfvxRaqE/A3Nt+owsbtMayxtyf + ClbyVY3fTk+bpZBNpcRstjLS3B4S+ezV2OB0yBk8qVU95jnNXdp8QCQacb2Yqip0 + GgK4G/A2QD2QX5/JJDKw + -----END CERTIFICATE----- + ``` + +5. Log the web client into Conjur and request a client certificate from tbe + Conjur CA + ```sh-session + $ ./4_create_client_cert + Password for mutual-tls/client: # client password from above + { + "certificate": "-----BEGIN CERTIFICATE-----\nMIIEWzCCAkOgAwIBAgIURYI21GXLvdTyeky0S0n5UsBqyzcwDQYJKoZIhvcNAQEL\nBQAwUjELMAkGA1UEBhMCVVMxCjAIBgNVBAgMAS4xCjAIBgNVBAcMAS4xCjAIBgNV\nBAoMAS4xHzAdBgNVBAMMFkNvbmp1ciBJbnRlcm1lZGlhdGUgQ0EwHhcNMTgwODIy\nMTkxNzQ3WhcNMTgwODIzMTkxNzQ3WjBCMQswCQYDVQQGEwJVUzEKMAgGA1UECAwB\nLjEKMAgGA1UEBwwBLjEKMAgGA1UECgwBLjEPMA0GA1UEAwwGY2xpZW50MIIBIjAN\nBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3RD53ArA+/Xp01JudfFrPJL8aJA0\ni/Q+tyVcz6AuQ8YGBKTvX1bR5hajAKJj8Ceh/eBgcqKBPVkAxHRD4KU1zoWNxTzo\nX2bWtAWF3/n4En2eWKsVmUa+rcGbvsNtvumGC4COBFcSakfoz3lC2l6R3r/k/XmY\nIgCkGTJQ4UEYdXKIh28TBevegCd1sjOzY4Hm9VM5wX7I6uMbhNQjD+sqDaywWrdL\neM65efXgxe9wcco52zjdEnP1OESF/Yvt2PHmjRCnkrUHZsSDCa324ZWsVbk7vyqm\nc6mGh7EsKiPrqJM16FyyWjo3CsqJbMTj7FjT2JFk4DGurgG7qm0Z6/ifMQIDAQAB\nozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU/vRh/m1mk3Zj\n/dWZx4vxbCrDW+YwDQYJKoZIhvcNAQELBQADggIBALBbB+TFNpaXpXrYqEPrXIaO\nLqo+RHFRHD6GcKivvYi8P2M2S4dTEWw2JVwLtn/KWsBWBfpDWuMmd/LddIm/VcU0\nOpSsJK8HfVABEMMuEJPV3zZi2esb/zkDa3l+j2mj+AOIdmaKZYE5ig8JUN9jE7wq\nzv6GSfNWEoEzYsdqB+DMymO61viwh334hCejA9St1F5uxqb8dszCqevZbpCJR78G\n5zuqXmJRHlL08tK+hsICQakEqZbvYG8BkcjVkmSyMCAnTcsiqcvYZZlicpyY6akf\nQndbU3ASXjC2+XCrL2QAX8NyPPDgci7cLJKCeKh0MRCDoE+9iCp3xPF24fSW+xPR\nUGySBHSA5bHBCocOoO6aTZvt6yKzDWsTCzPSWcP4CKfx5odsF44CI30Qxq5eJzdO\nF07BQ8FNGlVC6nIn53LXDBytZjtGFzCJ6rEc3f19BtKojZlS42+6ZRR2r9gQ/3rR\ncDeG+5sYB9+Kqz/hZZpdbZzFD6SIJttAlwdvrUQVCmCmNdGaKdnV7nHxLrtQb7Mu\nyCIDVstROyxukDi2w//NeH8a3XOaKeg6SwLqO4KsgltKvqygwI1+HVn21DaqS1+o\n45WVDQekW2cUaX+R57sLXfoaQBkP6EK48mvA1zoWY4MNDcS1UTRVtvZaxhyId9hj\nKfNGS61ysUORIt87m7AR\n-----END CERTIFICATE-----\n" + } + ``` + +6. Establish a connection between the client and host with mutual TLS using + the issued certificates + ```sh-session + # Connection with no certificate chain to validate server and no client certificate + $ ./5_connect + Starting server... + Connecting client (Certificate Chain=false, Client Certificate=false)... + curl: (60) SSL certificate problem: unable to get local issuer certificate + More details here: https://curl.haxx.se/docs/sslcerts.html + + curl failed to verify the legitimacy of the server and therefore could not + establish a secure connection to it. To learn more about this situation and + how to fix it, please visit the web page mentioned above. + + + # Connection with server certificate chain but no client certificate + $ ./5_connect --ca-chain + Starting server... + Connecting client (Certificate Chain=true, Client Certificate=false)... + + 400 No required SSL certificate was sent + +

400 Bad Request

+
No required SSL certificate was sent
+
nginx/1.15.2
+ + + + + # Connection with server certificate chain and client certificate + $ ./5_connect --ca-chain --client-cert + Starting server... + Connecting client (Certificate Chain=true, Client Certificate=true)... +

Hello, from a Conjur secured host!

+ ``` + +7. Clean up the example environment + ```sh-session + ./6_stop + ``` diff --git a/demos/certificate-authority/mutual-tls/ca/Dockerfile b/demos/certificate-authority/mutual-tls/ca/Dockerfile new file mode 100644 index 00000000..d168a60a --- /dev/null +++ b/demos/certificate-authority/mutual-tls/ca/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu + +RUN apt-get update -y && \ + apt-get install -y openssl + +RUN mkdir -p /root +WORKDIR /tmp/ca + +COPY generate_ca generate_ca + +CMD [ "/tmp/ca/generate_ca" ] diff --git a/demos/certificate-authority/mutual-tls/ca/generate_ca b/demos/certificate-authority/mutual-tls/ca/generate_ca new file mode 100755 index 00000000..40c815fd --- /dev/null +++ b/demos/certificate-authority/mutual-tls/ca/generate_ca @@ -0,0 +1,53 @@ +#!/bin/bash -eu + +rm -rf ca +mkdir -p ca + +# Generate a root CA key +openssl genrsa -aes256 \ + -out ca/root.key 4096 +chmod 400 ca/root.key + +# Generate a root CA certificate +openssl req -new -x509 -sha256 -days 730 \ + -config openssl.conf \ + -subj "/C=US/ST=./L=./O=./CN=Conjur Root CA" \ + -extensions v3_ca \ + -key ca/root.key \ + -out ca/root.crt +chmod 444 ca/root.crt + +# Generate an intermediate CA key +openssl genrsa \ + -out ca/intermediate.key 4096 +chmod 400 ca/intermediate.key + +# Generate a CSR for the intermediate certificate +openssl req -new -sha256 \ + -subj "/C=US/ST=./L=./O=./CN=Conjur Intermediate CA" \ + -key ca/intermediate.key \ + -out ca/intermediate.csr + +# Sign the intermediate CA with the root cert +openssl x509 -req -days 1000 \ + -extfile openssl.conf \ + -in ca/intermediate.csr \ + -extensions v3_intermediate_ca \ + -CA ca/root.crt \ + -CAkey ca/root.key \ + -CAcreateserial \ + -out ca/intermediate.crt +chmod 444 ca/intermediate.crt + +# Verify the intermediate certificate +openssl x509 -noout -text \ + -in ca/intermediate.crt + +# Verify the intermediate cert against the root cert +openssl verify -CAfile ca/root.crt \ + ca/intermediate.crt + +cat ca/intermediate.crt \ + ca/root.crt > ca/ca-chain.crt +chmod 444 ca/ca-chain.crt + diff --git a/demos/certificate-authority/mutual-tls/ca/openssl.conf b/demos/certificate-authority/mutual-tls/ca/openssl.conf new file mode 100644 index 00000000..e578d10c --- /dev/null +++ b/demos/certificate-authority/mutual-tls/ca/openssl.conf @@ -0,0 +1,25 @@ +[ req ] +distinguished_name = req_distinguished_name +prompt = no + +[ req_distinguished_name ] +C = US +ST = MA +L = Newton +O = CyberArk Software +OU = Conjur +CN = conjur.org + +[ v3_ca ] +# Extensions for a typical CA (`man x509v3_config`). +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ v3_intermediate_ca ] +# Extensions for a typical intermediate CA (`man x509v3_config`). +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign \ No newline at end of file diff --git a/demos/certificate-authority/mutual-tls/cli/mutual_tls.yml b/demos/certificate-authority/mutual-tls/cli/mutual_tls.yml new file mode 100644 index 00000000..178a6438 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/cli/mutual_tls.yml @@ -0,0 +1,33 @@ +- !policy + id: conjur/mutual-tls/ca + body: + + - !variable private-key + - !variable cert-chain + + # Signed certificates will be valid for up to a year + - !webservice + annotations: + ca/private-key: conjur/mutual-tls/ca/private-key + ca/certificate-chain: conjur/mutual-tls/ca/cert-chain + ca/max_ttl: P1D + + - !group clients + + # Allow hosts in the `clients` group to be signed + - !permit + role: !group clients + privilege: [ sign ] + resource: !webservice + +- !policy + id: mutual-tls + body: + - !host server + - !host client + +- !grant + role: !group conjur/mutual-tls/ca/clients + members: + - !host mutual-tls/server + - !host mutual-tls/client diff --git a/demos/certificate-authority/mutual-tls/client/Dockerfile b/demos/certificate-authority/mutual-tls/client/Dockerfile new file mode 100644 index 00000000..bd405cfd --- /dev/null +++ b/demos/certificate-authority/mutual-tls/client/Dockerfile @@ -0,0 +1,12 @@ +FROM ubuntu + +RUN apt-get update -y && \ + apt-get install -y \ + openssl \ + jq \ + curl + +# The 2 lines above prevent the `Can't load /root/.rnd into RNG` error +RUN touch .rnd && chmod 060 .rnd + +ADD request_certificate /client/request_certificate diff --git a/demos/certificate-authority/mutual-tls/client/request_certificate b/demos/certificate-authority/mutual-tls/client/request_certificate new file mode 100755 index 00000000..d3c61376 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/client/request_certificate @@ -0,0 +1,50 @@ +#!/bin/bash -e + +# Generate private key for client and certificate signing request (CSR) +if [ ! -f /client/client.key ]; then + openssl genrsa -out /client/client.key 2048 + chmod 400 /client/client.key +fi + +openssl req -new -sha256 \ + -subj "/C=US/ST=./L=./O=./CN=client" \ + -key /client/client.key \ + -out /client/client.csr + +# Read Password +echo -n Password for $CONJUR_AUTHN_LOGIN: +read -s api_key +echo + +urlencode() { + # urlencode + old_lc_collate=$LC_COLLATE + LC_COLLATE=C + + local length="${#1}" + for (( i = 0; i < length; i++ )); do + local c="${1:i:1}" + case $c in + [a-zA-Z0-9.~_-]) printf "$c" ;; + *) printf '%%%02X' "'$c" ;; + esac + done + + LC_COLLATE=$old_lc_collate +} + +# Authenticate with Conjur as a host +# api_key=$(curl -v --user "$CONJUR_AUTHN_LOGIN:$password" \ +# "$CONJUR_APPLIANCE_URL/authn/$CONJUR_ACCOUNT/login") +encoded_login=$(urlencode "$CONJUR_AUTHN_LOGIN") +token=$(curl -s -X POST -d $api_key \ + "$CONJUR_APPLIANCE_URL/authn/$CONJUR_ACCOUNT/host%2F$encoded_login/authenticate" \ + | base64 | tr -d '\r\n') + +# Request a certificate from the CA configured in Conjur +ca_response=$(curl -s -X POST -d "ttl=P1D" --data-urlencode "csr@/client/client.csr" \ + -H "Authorization: Token token=\"$token\"" \ + "$CONJUR_APPLIANCE_URL/ca/$CONJUR_ACCOUNT/$CA_SERVICE_ID/sign") + +echo $ca_response | jq . +echo $ca_response | jq -r .certificate > /client/client.crt \ No newline at end of file diff --git a/demos/certificate-authority/mutual-tls/conjur/.gitkeep b/demos/certificate-authority/mutual-tls/conjur/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/demos/certificate-authority/mutual-tls/docker-compose.yml b/demos/certificate-authority/mutual-tls/docker-compose.yml new file mode 100644 index 00000000..f5ccf4b0 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/docker-compose.yml @@ -0,0 +1,66 @@ +version: "3" +services: + + # nginx web server + server: + build: ./server + environment: + CONJUR_APPLIANCE_URL: http://conjur + CONJUR_ACCOUNT: cucumber + CONJUR_AUTHN_LOGIN: mutual-tls/server + CA_SERVICE_ID: mutual-tls + ports: + - "9080:80" + - "9443:443" + volumes: + - ./server:/server + + # curl web client + client: + build: ./client + environment: + CONJUR_APPLIANCE_URL: http://conjur + CONJUR_ACCOUNT: cucumber + CONJUR_AUTHN_LOGIN: mutual-tls/client + CA_SERVICE_ID: mutual-tls + volumes: + - ./client:/client + + # Service for generating our root and intermediate CA + ca: + build: ./ca + volumes: + - ./ca:/tmp/ca + + conjur: + image: cyberark/conjur + command: server + environment: + DATABASE_URL: postgres://postgres@database/postgres + CONJUR_DATA_KEY: + depends_on: [ database ] + ports: + - "8080:80" + expose: + - "80" + + database: + image: postgres:9.4 + environment: + POSTGRES_HOST_AUTH_METHOD: trust + + cli: + image: cyberark/conjur-cli:5 + working_dir: /src/cli + entrypoint: bash + environment: + CONJUR_APPLIANCE_URL: http://conjur + CONJUR_ACCOUNT: cucumber + CONJUR_AUTHN_LOGIN: admin + + volumes: + - ./cli:/src/cli + - ./cli/cache:/root + +volumes: + certs: diff --git a/demos/certificate-authority/mutual-tls/nginx.conf b/demos/certificate-authority/mutual-tls/nginx.conf new file mode 100644 index 00000000..e4bad8db --- /dev/null +++ b/demos/certificate-authority/mutual-tls/nginx.conf @@ -0,0 +1,32 @@ + +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/demos/certificate-authority/mutual-tls/server/Dockerfile b/demos/certificate-authority/mutual-tls/server/Dockerfile new file mode 100644 index 00000000..c9982e56 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/server/Dockerfile @@ -0,0 +1,10 @@ +FROM nginx + +RUN apt-get update -y && \ + apt-get install -y \ + openssl \ + jq \ + curl + +ADD request_certificate /server/request_certificate +ADD nginx.conf /etc/nginx/conf.d/server.conf \ No newline at end of file diff --git a/demos/certificate-authority/mutual-tls/server/content/index.html b/demos/certificate-authority/mutual-tls/server/content/index.html new file mode 100644 index 00000000..cd8dbe63 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/server/content/index.html @@ -0,0 +1 @@ +

Hello, from a Conjur secured host!

\ No newline at end of file diff --git a/demos/certificate-authority/mutual-tls/server/nginx.conf b/demos/certificate-authority/mutual-tls/server/nginx.conf new file mode 100644 index 00000000..a991c5a7 --- /dev/null +++ b/demos/certificate-authority/mutual-tls/server/nginx.conf @@ -0,0 +1,29 @@ +server { + listen 80; + + server_name server localhost; + + location / { + rewrite ^ https://$host$request_uri? permanent; + } + +} +server { + listen 443 ssl; + + server_name server localhost; + + location / { + root /server/content; + index index.html; + } + + # Certificate information presented by host + ssl_certificate /server/server.crt; + ssl_certificate_key /server/server.key; + + # Client certificates accepted by host + ssl_client_certificate /server/ca-chain.crt; + ssl_verify_client on; + +} \ No newline at end of file diff --git a/demos/certificate-authority/mutual-tls/server/request_certificate b/demos/certificate-authority/mutual-tls/server/request_certificate new file mode 100755 index 00000000..096dbb4f --- /dev/null +++ b/demos/certificate-authority/mutual-tls/server/request_certificate @@ -0,0 +1,51 @@ +#!/bin/bash -e + +# Generate private key for server and certificate signing request (CSR) +if [ ! -f /server/server.key ]; then + openssl genrsa -out /server/server.key 2048 + chmod 400 /server/server.key +fi + +openssl req -new -sha256 \ + -subj "/C=US/ST=./L=./O=./CN=server" \ + -key /server/server.key \ + -out /server/server.csr + +# Read Password +echo -n Password for $CONJUR_AUTHN_LOGIN: +read -s api_key +echo + +urlencode() { + # urlencode + old_lc_collate=$LC_COLLATE + LC_COLLATE=C + + local length="${#1}" + for (( i = 0; i < length; i++ )); do + local c="${1:i:1}" + case $c in + [a-zA-Z0-9.~_-]) printf "$c" ;; + *) printf '%%%02X' "'$c" ;; + esac + done + + LC_COLLATE=$old_lc_collate +} + +# Authenticate with Conjur as a host +# api_key=$(curl -v --user "$CONJUR_AUTHN_LOGIN:$password" \ +# "$CONJUR_APPLIANCE_URL/authn/$CONJUR_ACCOUNT/login") +encoded_login=$(urlencode "$CONJUR_AUTHN_LOGIN") +token=$(curl -s -X POST -d $api_key \ + "$CONJUR_APPLIANCE_URL/authn/$CONJUR_ACCOUNT/host%2F$encoded_login/authenticate" \ + | base64 | tr -d '\r\n') + +# Request a certificate from the CA configured in Conjur +ca_response=$(curl -s -X POST -d "ttl=P1D" --data-urlencode "csr@/server/server.csr" \ + -H "Authorization: Token token=\"$token\"" \ + -H "Accept: application/x-pem-file" \ + "$CONJUR_APPLIANCE_URL/ca/$CONJUR_ACCOUNT/$CA_SERVICE_ID/sign") + +echo "$ca_response" +echo "$ca_response" > /server/server.crt diff --git a/demos/cluster/README.md b/demos/cluster/README.md new file mode 100644 index 00000000..374d75f9 --- /dev/null +++ b/demos/cluster/README.md @@ -0,0 +1,98 @@ +# Cluster Demo + +This script configures a high availability DAP cluster with a master, follower and standby(s). The master cluster is load balanced for auto-failover. + +Optionally, clusters can be configured with any or all of the following: + +- Sample data +- Master Key encryption +- Custom third party certificates +- Disaster Recovery +- Particular Conjur version + +### Requirements + +To run this demo, you'll need the following installed: + +- Docker +- Docker Composes +- Access to the Conjur Docker repository (or the Conjur Appliance Image locally) +- Bash + +### Provision a Cluster + +To view all options available, run the following: + +``` +$ bin/start --help + +Provisions a Conjur cluster locally, using Docker. + +Usage: start [options] + + --auto-failover Configures the cluster for auto-failover + --custom-certs Installs custom certificates from the "files/certs" folder + --disaster-recovery Configures the cluster with a single Disaster Recovery node (only if the cluster is Auto-Failover) + -h, --help Shows this help message. + --load-data Loads sample policy along once th cluster + --master-key Encrypts certificates using a master key + --tag Starts a cluster with a particular appliance (defaults to 5.0-stable) + +``` + +#### Basic + +To stand up a simple cluster, without Master Key encryption, custom certificates, or sample data, run: +``` +$ bin/start +``` + +#### Auto-Failover Cluster +To configure an Auto-Failover cluster, run: +``` +$ bin/start --auto-failover +``` + +#### Master Key Encryption +To configure a cluster with encrypted certificates using a master key: + +``` +$ bin/start --master-key +``` + +#### Custom Certificates +To configure a cluster using custom certificates: + +``` +$ bin/start --custom-certs +``` + +#### Sample Data +To load a configured cluster with sample data: +``` +$ bin/start --load-data +``` + +#### Run a cluster with a particular Conjur version +To run a particular version of Conjur, pass the image tag in with the `--tag` flag: + +``` +$ bin/start --tag 5.2.2-20181029194559-7305fae +``` + +#### Master Key Encryption, Custom Certificates +Flags can be combined to provide combinations of these actions. Below is an example of how to configure a cluster with custom certificates, encrypted with a master key, and load sample data into the cluster: + +``` +$ bin/start --master-key --custom-certs --load-data +``` + +### Logging into your Cluster +Navigate to [localhost](https://localhost) and login with the username: `admin` +and the password: `MySecretP@ss1`. + +### Cleanup +To shutdown and cleanup your cluster after your done working, run: +``` +$ bin/stop +``` diff --git a/demos/cluster/bin/cli b/demos/cluster/bin/cli new file mode 100755 index 00000000..99eda4ba --- /dev/null +++ b/demos/cluster/bin/cli @@ -0,0 +1,29 @@ +#!/bin/bash -e + +function print_help() { + cat << EOF +NAME + cli - Development tool to simplify working with a Conjur container. CLI + proxies commands into the Conjur CLI container to simplify the process + of managing policy for development. + +SYNOPSIS + cli [global options] command [command options] [arguments...] +GLOBAL OPTIONS + --help - Show this message +EOF +exit +} + +function proxy_command { + cmd="$@" + docker-compose run --rm -w /src/cli --entrypoint /bin/bash client -c " + if [ ! -e /root/conjur-demo.pem ]; then + yes 'yes' | conjur init -u https://conjur-master-1.mycompany.local -a demo + fi + conjur authn login -u admin -p 'SEcret12!!!!' + eval exec \"$cmd\" + " +} + +proxy_command "$@" diff --git a/demos/cluster/bin/start b/demos/cluster/bin/start new file mode 100755 index 00000000..bffc8745 --- /dev/null +++ b/demos/cluster/bin/start @@ -0,0 +1,197 @@ +#!/bin/bash -ex + +function print_help() { + cat << EOF + +Provisions a Conjur cluster locally, using Docker. + +Usage: start [options] + + --auto-failover Configures the cluster for auto-failover + --custom-certs Installs custom certificates from the "files/certs" folder + -h, --help Shows this help message. + --load-data Loads sample policy along once th cluster + --master-key Encrypts certificates using a master key + -t, --tag Starts a cluster with a particular appliance (defaults to 5.0-stable) + +EOF + exit +} + +# Determine which extra services should be loaded when working with authenticators +# export VERSION=5.2.2-20181029194559-7305fae +TAG=5.0-stable +AUTO_FAILOVER=false +LOAD_DATA=false +MASTER_KEY=false +CUSTOM_CERTS=false +while true ; do + case "$1" in + --auto-failover ) AUTO_FAILOVER=true ; shift ;; + --load-data ) LOAD_DATA=true ; shift ;; + --master-key ) MASTER_KEY=true ; shift ;; + --custom-certs ) CUSTOM_CERTS=true ; shift ;; + -t | --tag ) shift ; TAG=$1 ; shift ;; + -h | --help ) print_help ; shift ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac +done + +export VERSION=$TAG + +if [[ $AUTO_FAILOVER = true ]]; then + docker-compose up -d --no-deps conjur-master-1.mycompany.local \ + conjur-master-2.mycompany.local \ + conjur-master-3.mycompany.local \ + conjur-master-4.mycompany.local \ + conjur-follower.mycompany.local +else + docker-compose up -d --no-deps conjur-master-1.mycompany.local \ + conjur-master-2.mycompany.local \ + conjur-follower.mycompany.local +fi + +docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke configure master \ + --accept-eula \ + -h conjur-master-1.mycompany.local \ + -p 'SEcret12!!!!' demo +" + +if [[ $AUTO_FAILOVER = true ]]; then + bin/cli conjur policy load --replace root policy/root.yml + bin/cli conjur policy load conjur policy/cluster.yml +fi + +if [[ $CUSTOM_CERTS = true ]]; then + docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke ca import -r /conjur_files/certs/ca-chain.cert.pem + evoke ca import -k /conjur_files/certs/conjur-master-1.mycompany.local.key.pem -s /conjur_files/certs/conjur-master-1.mycompany.local.cert.pem + evoke ca import -k /conjur_files/certs/conjur-master-2.mycompany.local.key.pem /conjur_files/certs/conjur-master-2.mycompany.local.cert.pem + evoke ca import -k /conjur_files/certs/conjur-follower.mycompany.local.key.pem /conjur_files/certs/conjur-follower.mycompany.local.cert.pem + " + if [[ $AUTO_FAILOVER = true ]]; then + docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke ca import -k /conjur_files/certs/conjur-master-3.mycompany.local.key.pem /conjur_files/certs/conjur-master-3.mycompany.local.cert.pem + evoke ca import -k /conjur_files/certs/conjur-master-4.mycompany.local.key.pem /conjur_files/certs/conjur-master-4.mycompany.local.cert.pem + " + fi +fi + +if [[ $AUTO_FAILOVER = true && $CUSTOM_CERTS = false ]]; then + docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke ca issue conjur-master-2.mycompany.local + evoke ca issue conjur-master-3.mycompany.local + evoke ca issue conjur-master-4.mycompany.local + " +fi + +if [[ $CUSTOM_CERTS = false ]]; then + docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke ca issue conjur-follower.mycompany.local + " +fi + +if [[ $MASTER_KEY = true ]]; then + docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke keys encrypt /conjur_files/master-key + evoke keys unlock /conjur_files/master-key + sv start conjur + /opt/conjur/evoke/bin/wait_for_conjur + " +fi + +docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke seed standby conjur-master-2.mycompany.local conjur-master-1.mycompany.local > /opt/conjur/backup/standby-seed-2.tar + evoke seed follower conjur-follower.mycompany.local > /opt/conjur/backup/follower-seed.tar +" +if [[ $AUTO_FAILOVER = true ]]; then + docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke seed standby conjur-master-3.mycompany.local conjur-master-1.mycompany.local > /opt/conjur/backup/standby-seed-3.tar + evoke seed standby conjur-master-4.mycompany.local conjur-master-1.mycompany.local > /opt/conjur/backup/standby-seed-4.tar + " +fi + +# Setup the standby +docker-compose exec conjur-master-2.mycompany.local bash -c " + evoke unpack seed /opt/conjur/backup/standby-seed-2.tar +" +if [[ $MASTER_KEY = true ]]; then + docker-compose exec conjur-master-2.mycompany.local bash -c " + evoke keys exec -m /conjur_files/master-key -- evoke configure standby + " +else + docker-compose exec conjur-master-2.mycompany.local bash -c " + evoke configure standby + " +fi + +if [[ $AUTO_FAILOVER = true ]]; then + # Setup the standby + docker-compose exec conjur-master-3.mycompany.local bash -c " + evoke unpack seed /opt/conjur/backup/standby-seed-3.tar + " + if [[ $MASTER_KEY = true ]]; then + docker-compose exec conjur-master-3.mycompany.local bash -c " + evoke keys exec -m /conjur_files/master-key -- evoke configure standby + " + else + docker-compose exec conjur-master-3.mycompany.local bash -c " + evoke configure standby + " + fi + + # Setup the standby + docker-compose exec conjur-master-4.mycompany.local bash -c " + evoke unpack seed /opt/conjur/backup/standby-seed-4.tar + " + if [[ $MASTER_KEY = true ]]; then + docker-compose exec conjur-master-4.mycompany.local bash -c " + evoke keys exec -m /conjur_files/master-key -- evoke configure standby + " + else + docker-compose exec conjur-master-4.mycompany.local bash -c " + evoke configure standby + " + fi + + docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke replication sync + " + + docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke cluster enroll -n conjur-master-1.mycompany.local conjur + " + docker-compose exec conjur-master-2.mycompany.local bash -c " + evoke cluster enroll -n conjur-master-2.mycompany.local -m conjur-master-1.mycompany.local conjur + " + docker-compose exec conjur-master-3.mycompany.local bash -c " + evoke cluster enroll -n conjur-master-3.mycompany.local -m conjur-master-1.mycompany.local conjur + " + docker-compose exec conjur-master-4.mycompany.local bash -c " + evoke cluster enroll -n conjur-master-4.mycompany.local -m conjur-master-1.mycompany.local conjur + " +fi + +# Setup the follower +docker-compose exec conjur-follower.mycompany.local bash -c " + evoke unpack seed /opt/conjur/backup/follower-seed.tar +" +if [[ $MASTER_KEY = true ]]; then + docker-compose exec conjur-follower.mycompany.local bash -c " + evoke keys exec -m /conjur_files/master-key -- evoke configure follower + " +else + docker-compose exec conjur-follower.mycompany.local bash -c " + evoke configure follower + " +fi + +rm -rf cli_cache +if [[ $LOAD_DATA = true ]]; then + bin/cli conjur policy load root policy/users.yml + bin/cli conjur policy load root policy/policy.yml + bin/cli conjur policy load staging policy/apps/myapp.yml + bin/cli conjur policy load production policy/apps/myapp.yml + bin/cli conjur policy load root policy/application_grants.yml +fi diff --git a/demos/cluster/bin/stop b/demos/cluster/bin/stop new file mode 100755 index 00000000..45ee6ea0 --- /dev/null +++ b/demos/cluster/bin/stop @@ -0,0 +1,5 @@ +#!/bin/bash -ex + +docker-compose down -v + +rm -rf cli_cache diff --git a/demos/cluster/cli b/demos/cluster/cli new file mode 100755 index 00000000..37658dcf --- /dev/null +++ b/demos/cluster/cli @@ -0,0 +1,29 @@ +#!/bin/bash -e + +function print_help() { + cat << EOF +NAME + cli - Development tool to simplify working with a Conjur container. CLI + proxies commands into the Conjur CLI container to simplify the process + of managing policy for development. + +SYNOPSIS + cli [global options] command [command options] [arguments...] +GLOBAL OPTIONS + --help - Show this message +EOF +exit +} + +function proxy_command { + cmd="$@" + docker-compose run --rm -w /src/cli --entrypoint /bin/bash client -c " + if [ ! -e /root/conjur-demo.pem ]; then + yes 'yes' | conjur init -u https://conjur-master-1.mycompany.local -a demo + fi + conjur authn login -u admin -p MySecretP@ss1 + eval exec \"$cmd\" + " +} + +proxy_command "$@" diff --git a/demos/cluster/docker-compose.yml b/demos/cluster/docker-compose.yml new file mode 100644 index 00000000..9c1c79db --- /dev/null +++ b/demos/cluster/docker-compose.yml @@ -0,0 +1,120 @@ +version: "3" +services: + conjur-master-1.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + ports: + - "443:443" + expose: + - "443" + - "5432" + - "1999" + environment: + RESTCLIENT_LOG: stdout + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - ./system/backup:/opt/cyberark/dap/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs:/var/log/conjur:Z + - ./files:/conjur_files + + conjur-master-2.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + ports: + - "444:443" + expose: + - "443" + - "5432" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - ./system/backup:/opt/cyberark/dap/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs:/var/log/conjur:Z + - ./files:/conjur_files + + conjur-master-3.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + ports: + - "445:443" + expose: + - "443" + - "5432" + - "1999" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - ./system/backup:/opt/cyberark/dap/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs:/var/log/conjur:Z + - ./files:/conjur_files + + conjur-master-4.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + ports: + - "446:443" + expose: + - "443" + - "5432" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - ./system/backup:/opt/cyberark/dap/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs:/var/log/conjur:Z + - ./files:/conjur_files + + # conjur-standby.mycompany.local: + # image: registry.tld/conjur-appliance:5.0-stable + # expose: + # - "443" + # - "5432" + # security_opt: + # - "seccomp:unconfined" + # volumes: + # - seeds:/opt/cyberark/dap/seeds + # - ./files:/conjur_files + + conjur-follower.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + ports: + - "447:443" + expose: + - "443" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - ./system/backup:/opt/cyberark/dap/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs:/var/log/conjur:Z + - ./files:/conjur_files + + client: + image: cyberark/conjur-cli:5 + working_dir: /src/cli + environment: + CONJUR_APPLIANCE_URL: https://conjur-master-1.mycompany.local + CONJUR_ACCOUNT: demo + CONJUR_AUTHN_LOGIN: admin + volumes: + - .:/src/cli + - ./cli_cache/master:/root + + follower-client: + image: cyberark/conjur-cli:5 + working_dir: /src/cli + environment: + CONJUR_APPLIANCE_URL: https://conjur-follower.mycompany.local + CONJUR_ACCOUNT: demo + CONJUR_AUTHN_LOGIN: admin + volumes: + - .:/src/cli + - ./cli_cache/follower:/root + +volumes: + seeds: diff --git a/demos/cluster/files/certs/ca-chain.cert.pem b/demos/cluster/files/certs/ca-chain.cert.pem new file mode 100644 index 00000000..39a5dfd7 --- /dev/null +++ b/demos/cluster/files/certs/ca-chain.cert.pem @@ -0,0 +1,66 @@ +-----BEGIN CERTIFICATE----- +MIIFsTCCA5mgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwbDELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcMBk5ld3RvbjERMA8GA1UE +CgwIQ3liZXJBcmsxDzANBgNVBAsMBkNvbmp1cjEQMA4GA1UEAwwHUm9vdCBDQTAe +Fw0xODEwMTYxMjE0MzRaFw0yODEwMTMxMjE0MzRaMGMxCzAJBgNVBAYTAlVTMRYw +FAYDVQQIDA1NYXNzYWNodXNldHRzMREwDwYDVQQKDAhDeWJlckFyazEPMA0GA1UE +CwwGQ29uanVyMRgwFgYDVQQDDA9JbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQCtKHyzKxXByAsnoYekDqDPkLmP8n40Xf3CGnoZ +jv6Lfijc1+E2DdNQ8F6S+xvMkRK0OM9htvKTgCrkq2CruN6gKs1wH9lnSJS4vhbj +u8J6qIbGRqQ6QEJkkWnIlzNxnCYcaE3Ox4xmPL9NdrVj26kQbs9R7Dpj33RuirNe +1+OgCX20KC83TPvsiqflZr2qqxrmr3M8+RJjiA/QnOFT/DXRdvyOBTyLIXJ2q7VK +z2kJW1QxaY8wcVo3HGtNSt8G7Rp5pIKXZVYjRpqBg29Buw2jLl/AJ4W76B5DOnx6 +Oc0rTr6awaBYyRkv6RA1L/FB6vj7wyHFKTwQXT0eEUypE6y6b1C1NuFlhPBh7zgV +zXaZAjxSQl3xLbmnVzBpAsLzKyipo/LgNypq6vD1VjeSIAEXVNWdHJHxktO1EJaK +XNtPK20AR5zSobhWCm+4c0akxcWYEG4OmF/C0VrTMlcVoK9jBIuXQkaE4acEF/0k +JhQjb9caifSt9YMS66WXw16fraW97i0bAOBBCF3ZE3n0FdFJqQPVplTapxlatstg +dlnJCW7r3eSBNKIPy78A18GOTxI5XGb9G5z3CoudK19S41BWga7hH3rZ/TSyC6IO +QW2Ovxvp3zLYLrCa0orfKN04ruZ/h8kA6agARJ5yA2dZuqAsZlbCcKvxS8c+B/li +FCkHfQIDAQABo2YwZDAdBgNVHQ4EFgQUk2XkYo1a3Zn1FO8JDEkVHUV1SX8wHwYD +VR0jBBgwFoAUI8eAZyTvEPivpZfvh36JrDDURiowEgYDVR0TAQH/BAgwBgEB/wIB +ADAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBANCd5iDvnvq35roi +kwfMo49UFpjRJP3gyjeAi6jU4peRNQW4GZw6yUGp/D5jnwmxDyptFe/uGlDRjfDK +W54NH7Zez3vtIr14JQ0uboGx76ARRj8QK/lflecBsqA7ubfhTiIs6REzss4Z5yuR +A5ZLq0nN97BCvA4CsZTXzFeeiKq4YOTJDYEJF6QqzXlvfX0aE+qnrq76oSpSv71Y +hbjHNLDGbt9wbev6wZFHJL9t92IW6SEDObQ1cR8nAp2jVuj6oEj8oRoRiA3ZE/JN +WwXBUc/qFWVQQ8y7o3Vt2ab+BL5oFdh8vlVK/bhE9C8AiqyLTLYW2PrZEUkgyWil +KwxzUHfdpTbVU63crrFjgYoKpHsJ7LlA+ga0XtDXE//GNpJDQehm0lVcMAbu0nOW +3nkaBs5hWarpLsi1WpnQT9n2T3FUcA71qX95pPDbnX39NEClqzu/rnPjhf4VYThV +kzoU34SvovbVAPptv/o5n6Sp5YJ86IcF1b8YL8wEhPvI7kAm9ZUgTKaSWlR7JD0z +d6xo0d6uemwmO6vr/CBiTxNL64NGYpKONHeobTdP87BVVeF3Jw/7HI7awck5XzuN +3sF+fOtg7hTy1MnCCVml/ytzzed4GOd1UOSayNiAhAry9qA/S7qUpUCMLfFUm0PM +8DZakFWFeX09VEYlJVdW2tkfPIZE +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFvjCCA6agAwIBAgIJAPaGDD/4fRiuMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV +BAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMQ8wDQYDVQQHDAZOZXd0b24x +ETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYDVQQLDAZDb25qdXIxEDAOBgNVBAMMB1Jv +b3QgQ0EwHhcNMTgxMDE2MTIxNDI0WhcNMzgxMDExMTIxNDI0WjBsMQswCQYDVQQG +EwJVUzEWMBQGA1UECAwNTWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9uMREw +DwYDVQQKDAhDeWJlckFyazEPMA0GA1UECwwGQ29uanVyMRAwDgYDVQQDDAdSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3CWwf7IzmzLXp6YW +um+SzCeGxWaXaISVLBjpX2wRkPn3untWZiQUeCmqw6eIMInhi+/u5IPcXbpWm3sA +iHxrEMVHjec16RaZN1Oadz4ugzz+gMhw++1Pxz5y1PBViD41VapqPSCu6Elfhe/a +lSC7X2bBjx3FJKYVkDo+qAmJM0Gsthbxh9hWSxw1IWDrCF92cGQDo7/FHF5tUlkN +da5G4yad5t+1fZmdok1UXou1O45aaok5JTCP1djorxRa9xSTcowFcGiDOuHRyNqO +7B/kKY933rWsMV2A1WHeLl7Ln25A6G6PQBCQXZ81VvbAhvYalIO0sDPCz4hVJ3BM +sYxmC8LJ58Rl9D36n+dYCl6m7//02cGCoO3vg4ud6Qyrvhz/4NhXVfdHVScgK+bG +QAQOrDiIqCoOMrduan89pqkhTd7dTD7Y8xcXN7Tawb3m2wfM/TTW89X3n446NBmj +ezrT/I6h2Fx/+v/ZJZRkB5fDD4wMH4L9InDlX+fG0+8In8zsZ4f8vpIYvjVmQWJ8 +TYtIL2hwrtkG/fOrR7zcRLF/dhhN3sO4gvYru0D5V6ax8RK5n6yQ3t0PKfEjSsWf +bJObcJb+4KdTWvwdnzr0yCq0kqgNO7Y1ih4KgTwSTddqKLkqGppy10182EYTqpM5 +XKGSSPqI8kGdVHS7zmv9j3ljjj0CAwEAAaNjMGEwHQYDVR0OBBYEFCPHgGck7xD4 +r6WX74d+iaww1EYqMB8GA1UdIwQYMBaAFCPHgGck7xD4r6WX74d+iaww1EYqMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IC +AQDTWSbeiF9v3LBiLaGLDqVfif6FQtOvijYKhB1paHax1KJRpXMF8lQaWOG0fS3v +F+fCrHPKChi/DSHRr3W7r9voCMzKA+vVNrG2fX/lCvRSZa8A1uJJ79426vbGV7jj +r/mObRvwf3TLy5BowJFQP6YPO2V78KSBZkcohVsBvuXbt601pfqZja0lBQps0Yty +nSZzLDClGlm9WyHZXGKkNOtdrpontNc3xsg/XUfVyMXgwSPbUVtd2sZPt8ZKo67L +a4RNYm7L/i2nLTd11OUhsDz49hv7HSCF56qEyJGfcdeCPVojWKlZjPE+9TNKgxIN +9/O6jqTSG3PZmP68HHAi/nTwN2UHKkEfL1KkU/UN0pq3Ugod1Ji1peTtbBMFpydv +HKNW7ioQHBz65hcdXZndCG7dYB42p5xP7yExhDN89/G6HZo6rHu2oGgdQP+iGLjd +dl2d1Bx5F8G7zil/H0/hnHg6tdB/gJ1bQkT3NC9G9pKODZuiI+tNfwP84shpVufa +xawNHcKDfjSV44qq2yOAZw3aEwl+rlVgxgXt+BrI9A1FERsW3GylCTljgZLqGJr/ +fV/YtNqWeNgevOf2yln1eYQ7/HA4zz3ZDxE7xcvaIAHYU/rfH8rABqCzKBF/MFW8 +9b2W4i0zGYhyormvMo+sgJJx1SXFUcWVTKoxQepL/BZOtg== +-----END CERTIFICATE----- diff --git a/demos/cluster/files/certs/conjur-follower.mycompany.local.cert.pem b/demos/cluster/files/certs/conjur-follower.mycompany.local.cert.pem new file mode 100644 index 00000000..be156a8e --- /dev/null +++ b/demos/cluster/files/certs/conjur-follower.mycompany.local.cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEqjCCApKgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYD +VQQLDAZDb25qdXIxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0xODEwMTYx +MjE0NTNaFw0xOTEwMjYxMjE0NTNaMIGEMQswCQYDVQQGEwJVUzEWMBQGA1UECAwN +TWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9uMREwDwYDVQQKDAhDeWJlckFy +azEPMA0GA1UECwwGQ29uanVyMSgwJgYDVQQDDB9jb25qdXItZm9sbG93ZXIubXlj +b21wYW55LmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1wMI +e4mCVqxBTCS2fjgFtFAa09/cM60hEzwlM6HQIfNYeQKdW/zU2GsnQ6TCt4LfXwS2 +AonpPcC/9yIdsEIaNfddqvCCpyqxR3dsIsPNWIPudZntEdiRT+3k9jWMGbNluPNL +sWI8VDTNFm2OSdVIOh6j/eMDnbPUNvA08UBbnoCpMxFS3TBqtInHDPOTi2fPjbbE +D9/p0txdaRJjxeAexp9Le3DXpimGcgVn+lPU3oeQbSX3rateGa4obuCddcXQc/Mi +4AXrduTovvbrAEV0xymROluzVl6ytPkA0wwkUfEwxrU5xmZVAzEr+BT1+N6nX2Op +v7xXF9do+pDlTLimDwIDAQABo0YwRDBCBgNVHREEOzA5gh9jb25qdXItZm9sbG93 +ZXIubXljb21wYW55LmxvY2FsghZtYXN0ZXIubXljb21wYW55LmxvY2FsMA0GCSqG +SIb3DQEBCwUAA4ICAQBIT7Ef9bOZ+1hlMWAC/e++so7mNiIAe9Ov0bBt3QX4gngU +1oO5BryrPFjnxWm519eflF6m/WphmzoJuUjIjww5KFdiTM1IAVar9RqejMHaz954 +kJ99gKyUoOpAW0f1VtcaFz6SicQL+Zg2ZyevZqLvDU06uPdpcEQp/A0kksfwAkye +i2c6p6VKOZVxgqLAu3jwyIIkoVJeZkyIupfILtjvwnrTulAQ6k8H7ipXEGLB4+tZ +CTXbMQN/Ipo/5erAZMTv/L0gb1bhXFr9anYOYsjgMy/tyWYdlzKaq9O3jztYi6Ir +TPBUvls4lC6YC0X+H0a7Hx01kJrvA6C/SlF9WUfa3DBDe+/2Awsx2QnnLURD4/wO +/M8rr+yP/0GE5P33+zCDPRHai0ZAGQo1VhT3FkOoeMFQva7GLl2lq+Pnn81Ay3wS +lNZW89ha+sxCt2NO1sY427wUycOJO9MWwTpB7I8Yw5OVWNbXJJ+oxxMJ88U62/6y +GV7M+1BOJXnwx67kkByhqqGX5jEQ8y8T+1Wv/ApzAjcPJkwx+Ik7ftkwfj/YTIhu +5pK1b9oWx/aWSGJ4LIYlbBpXqZ5Va+YQ6UuMAtp9FqLohaw6JlZteIllzZGAtTrk +VHjBD8mTVM013Yt35erlrORURaBPIsC0+mQkYnU70zLce46Fjf0I49GF61Z9tA== +-----END CERTIFICATE----- diff --git a/demos/cluster/files/certs/conjur-follower.mycompany.local.key.pem b/demos/cluster/files/certs/conjur-follower.mycompany.local.key.pem new file mode 100644 index 00000000..3cea640d --- /dev/null +++ b/demos/cluster/files/certs/conjur-follower.mycompany.local.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA1wMIe4mCVqxBTCS2fjgFtFAa09/cM60hEzwlM6HQIfNYeQKd +W/zU2GsnQ6TCt4LfXwS2AonpPcC/9yIdsEIaNfddqvCCpyqxR3dsIsPNWIPudZnt +EdiRT+3k9jWMGbNluPNLsWI8VDTNFm2OSdVIOh6j/eMDnbPUNvA08UBbnoCpMxFS +3TBqtInHDPOTi2fPjbbED9/p0txdaRJjxeAexp9Le3DXpimGcgVn+lPU3oeQbSX3 +rateGa4obuCddcXQc/Mi4AXrduTovvbrAEV0xymROluzVl6ytPkA0wwkUfEwxrU5 +xmZVAzEr+BT1+N6nX2Opv7xXF9do+pDlTLimDwIDAQABAoIBAGKFg0eINO8eMzV+ +xRiE9yguZHydYTtUo4k60Bkelk5YQTwB1LUn3yfjwbQfNRH9p/jUIcp8AyJGxi+p +tEzlnTkJRiRj3JpY167Vq/kqG1fp7ER66cR5pewoJ/ghhTbpmzzqTs7TIq27HBag +0MhIMLZg/+gAM9H5as5Ztwis4s53cm4N7TaT8UYPiReEcAFGS3ZUjLK0iCQGzA3J +gwQeGTZvjfDN6+gjgx6vaybLL7qR1CN/EGFN1TqnX5u0mLv/UIHAXzvffnlgfxVN +mYi5QZtV5dUCvY3KVruf7zq6OCZfoA9245cHQL5WVNp9jGlXfhJNt4JcACClhHM9 +NP3aPAECgYEA/TOvUHmiB8zU/v2pTXJ2pDsv4/rZbIyz1nXRFLNldQNM80JCY9Th +WKwUNxFHM6MXYyWXFOPUeddawCfTmgZ+NO/TmZnrRJeeDZP/wBc0XEBKGVSfOrE9 +ivNJMg1EpwkRxWD6qBpI0ip7pdyxTFNa1RpgezTQ1wD5Lb44npBc3wECgYEA2WNO +v9/At9RHnrj0czrvuxRUaq9QW656F4JJvdjBtvASA2GkMOWx/rtMcSbIemDQkcI4 +SryfyGD504/EBS+MPrS5YjGsJnsrkqP1943g8eMqrmoSCdojP3kRFeXfD8C7w9vK +DuKqt85eKyPpIu4P1nuJ9euUENXGkwAt/cV8lQ8CgYEAvzdKHZdN82AQNuWv9uoL +iSmdmCk4C88SfVKKbHyykTTF5yvR4XzCFeoWdiPZRrjTD7AysbcBHmaxhU5OchKX +Ozkm7ugbkbiCxzROv22GwGhYzVpnybZSiN4EGAWHJDIoNoxvn4YCGp20tWS+jKqi +fS8nT8RqNwToKVBvh+f0CwECgYByZBVuVhmdIjFFzmGjuSGpOftp4DLS668Ha+HN +6p+U2iNAcELsEBJnzrtc12GrNALMkHz6puMVmCIeN4qYh/qujH74sta5sRquoWSv +DZOO9VDiUqKHWKgvoE9jTIDiUzL6z082IgRfkFJxNQZbARaIcJ2aMIrLiRJjDDcn +UKJL9QKBgEArkRUjAOET7eeUGyQlqz/lbIJvMxAznehrYyFaNnHeBFsNwPcVnB3M ++8kZguqSCBGFf8KuDHL8eN60CX9qSjy78aPVmPfkTog2crEEaAkVp1px29chXt3t +fkg8RURCpHDcV51Uw2CTFywi92Vpps18obYe5PReZT0pvCTMmCOm +-----END RSA PRIVATE KEY----- diff --git a/demos/cluster/files/certs/conjur-master-1.mycompany.local.cert.pem b/demos/cluster/files/certs/conjur-master-1.mycompany.local.cert.pem new file mode 100644 index 00000000..0549be4a --- /dev/null +++ b/demos/cluster/files/certs/conjur-master-1.mycompany.local.cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFGzCCAwOgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYD +VQQLDAZDb25qdXIxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0xODEwMTkx +NjI0MzZaFw0xOTEwMjkxNjI0MzZaMIGEMQswCQYDVQQGEwJVUzEWMBQGA1UECAwN +TWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9uMREwDwYDVQQKDAhDeWJlckFy +azEPMA0GA1UECwwGQ29uanVyMSgwJgYDVQQDDB9jb25qdXItbWFzdGVyLTEubXlj +b21wYW55LmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61Mj +dJdUotdhJxdn6Lo732SWntoFZ9bDgQo+AtB39TWFxRKbp96UfBgsFVKDSZClRKn0 +/0+wJyDo9R3jL9Gs0ruspqE2KkTmX6R4bKFMSdteD0HOukn6pSEDsniGLCJKzDGz +975Yi4MO9H95Q6ZwKEkWpm/hjnY2KL/Fb05u4CEBcsr5/WXGdDOkgxx+UKbooRmT +7P0u9daveYGzh5vOMXiy4WKtjn5AkpNE9MEIM4EuIzJx3ItYhqRWE9htHK3Rvxs5 ++hveZkBZMj1bl5RWRuvo96JPLZQHijzgyK/nS9qSHFAmKNoDKwPBQRtWY+2ykIfu +iuLGNcSrynwjy0TjNQIDAQABo4G2MIGzMIGwBgNVHREEgagwgaWCH2Nvbmp1ci1t +YXN0ZXItMS5teWNvbXBhbnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItMS5teWNvbXBh +bnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItMi5teWNvbXBhbnkubG9jYWyCH2Nvbmp1 +ci1tYXN0ZXItMy5teWNvbXBhbnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItNC5teWNv +bXBhbnkubG9jYWwwDQYJKoZIhvcNAQELBQADggIBAF4byWRHV3b06ojHfgpE8M5J +fHckDrhK/C75RA49riklhaczekwsBk8NMK0TKRGoXy5RgrIcktzwkY4N6Ljc+l5J +qEU8tZPGnIcbyNsKtlF9gC5ei05D0yMTTHEUr81DvRddCz/P1jMMgUWQep3hT+ba +nCQVFbHvKFljmlj39mUuFRTLEhklmPcDdq43N/6U8YNwX5g/A1rGW4bZTNqaX415 +dMPf78lOjHOqW4CO3M8Tx9JASwFgXoal8dRXuFFkY+Xjv3E4ToF1NYp0iwpU+4cJ +Jqt+RPGHzHozI91JJO1EDtsvg85+SOv7euDEPMmvKtosDJBwbvuuyyRk18G47zIu +CTlbtQdAcjWDQw2WeIh/ljRv+KIkP9HnbF1LcqYhK+VyeF2Hu2UkBYC/Z0w84UC9 +gccBid590c85Hq12Ws7PXoAJYuhkW4QuedoYE71gjNylyBF8ftZu7v0n7mr6+qYb +dXxzxZFJxax5Zp27hHnAFxPxpna0Wh/gEWHLgB4VByyIpV0QqmLCsxXgVkC2QvcW +wy42CgBVZzA3S5pmY4vN8lyE5LcGinxdC4hmw1ar5k1P65w2UOoqyV02K7jG8070 +0nSvtQ4r5Jod6jhzW/Yl4ZDQrzJXQwMBSLxZ++LOmydaDDxmoMpuwt31Bhd+Ww+I +Oj1m7uRCccaBeSwc+nxX +-----END CERTIFICATE----- diff --git a/demos/cluster/files/certs/conjur-master-1.mycompany.local.key.pem b/demos/cluster/files/certs/conjur-master-1.mycompany.local.key.pem new file mode 100644 index 00000000..b95804d7 --- /dev/null +++ b/demos/cluster/files/certs/conjur-master-1.mycompany.local.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA61MjdJdUotdhJxdn6Lo732SWntoFZ9bDgQo+AtB39TWFxRKb +p96UfBgsFVKDSZClRKn0/0+wJyDo9R3jL9Gs0ruspqE2KkTmX6R4bKFMSdteD0HO +ukn6pSEDsniGLCJKzDGz975Yi4MO9H95Q6ZwKEkWpm/hjnY2KL/Fb05u4CEBcsr5 +/WXGdDOkgxx+UKbooRmT7P0u9daveYGzh5vOMXiy4WKtjn5AkpNE9MEIM4EuIzJx +3ItYhqRWE9htHK3Rvxs5+hveZkBZMj1bl5RWRuvo96JPLZQHijzgyK/nS9qSHFAm +KNoDKwPBQRtWY+2ykIfuiuLGNcSrynwjy0TjNQIDAQABAoIBAFfbjl01MrApYWhK +4MyO21OoJmPgWixOjmda/5PlaSPve6X8MIkYHK/IBo1fZQzOKCXenk3D3qx9KPx6 +0BtGWRPEZc1AWwyk9K24pg1Im0bn09I2a4w5mo6UKOE1BkLr+qkJ1XslYcGUiLzX +6tpLBYzE3OP+2WNq1wWXs4q+6b5bXOYtDMuEbWHym9oUn0TCkOwfTYfmA+bH9E6a +JnyeQNyhsCUAtmSJf6MzTw/98+sODRh1uZgWJP9y9/sCXKTddsPL0oOT9araA73i +tFOb8l4go93Jj6wv/QapvkR7SXnXWCwzp+Vd9hSWPHc3JgMPdcqpgu40K7P5FLH2 +IRHY2vECgYEA/S5d4ar8EZKAyLIOizg8RNhVVLO3T7Un71AXMBmRZhvXQq+tmC+o +rTv2BEdzKgxa2y3uymZDwY3r4lQhY9t9Q28xdpxIiPfPHmYq4xjIx4pG/Yy87Y2g +xAjeBB4gp8tsF66kumr+IuPloywFEswE/wvRgx+/sSKaVvqA/itJNfcCgYEA7fHg +XL3fVtGLX+6DKLEGxEYmCNOJ9w6sNRDIP09bPxUkwdu8v5sEPLNIUGuL2XSCxTnJ +OD7/bZCOBYkeCLf7PfzawagrChzg/EX/yD0A0As//zq2CHb7aW+jh29ojsE/4KHb +7Lbka1zK/cIvXI4Zvb/lhtVnsoPnEgdnTIvVNTMCgYEAtF4w8dEfLOGjL9dx9wrE +HQPFnsc9o+JaJep36oN8izLwYwjG8jGZyHh8JsZELEOLArSxdq3uPVj/IElxVDON +BNqVcXubTUDF5FFC4nDIsSc4te9qtQ3950qt6F8SQpfwVNrNbiVFEdQrx9hXcPG5 +6X0g8HpQ1T/ilm52MRzjVjcCgYEA6AqT+P01Gu5YU+I+R+VzKt8Z4kug5KyLZWiL +T6os2rTc1qxaQiSDGkrf/4URqauEh59VyqMs5wUsatuPzYLV4Vp/XpGH/2GwSnRc +/0H2U+xUqarwsAqQHP9A4yfTODve9koCNbMZyFWCo7rGAyWUlsXXqQjeCmm1YpCT +vUM0VZ8CgYAOKQlbfvEJHwUg5tZJ+LczkmLIzfNc6yG3g0oQsztBrg4rJP0X2ZY6 +vLTVl9lKxvZmbepVuqtuJXfXGmtUQXVKVVVQh6/ufnyV4GtBuIl/oJ+Zx6nPALR9 +QPY/6UkXVNNO0CcZ3gZpk11cdN8HAin1oyLsDz3NijzCsqUTy3+uTQ== +-----END RSA PRIVATE KEY----- diff --git a/demos/cluster/files/certs/conjur-master-2.mycompany.local.cert.pem b/demos/cluster/files/certs/conjur-master-2.mycompany.local.cert.pem new file mode 100644 index 00000000..83f729d3 --- /dev/null +++ b/demos/cluster/files/certs/conjur-master-2.mycompany.local.cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFGzCCAwOgAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYD +VQQLDAZDb25qdXIxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0xODEwMTkx +NjI0NDJaFw0xOTEwMjkxNjI0NDJaMIGEMQswCQYDVQQGEwJVUzEWMBQGA1UECAwN +TWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9uMREwDwYDVQQKDAhDeWJlckFy +azEPMA0GA1UECwwGQ29uanVyMSgwJgYDVQQDDB9jb25qdXItbWFzdGVyLTIubXlj +b21wYW55LmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5/z +55JtZjTRrcjDz/jAd5M7UaAyAmpCDy3u9mDLNAb47+tH7yloVHagK3qZN4DaaPju +iyw8dPkw3j+eUY9k62JPe2jxfP7Ns23kH0yOaF8Ri84BoIr0wjvRiR5eQdvDTeq/ +RGp9jNFZ/oajQcZ+bv66j4eD0YRvGrhLIq86RX/fCm1llLIpHaOA8+GcvHF8f3vc +5nH9fP0mCwOB/QntpFw9di3rtTlVA9qsGk9imPZCGZ1zFRuzjedb/1eV+is19303 +2Qoy/0VtoBbKO1OFq+eV5Tfhj+57cWj5c3YM8hctFpOr7oFKWKF08MGpMEY5E0V7 +V+q+on0uswd1jwzSDQIDAQABo4G2MIGzMIGwBgNVHREEgagwgaWCH2Nvbmp1ci1t +YXN0ZXItMi5teWNvbXBhbnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItMS5teWNvbXBh +bnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItMi5teWNvbXBhbnkubG9jYWyCH2Nvbmp1 +ci1tYXN0ZXItMy5teWNvbXBhbnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItNC5teWNv +bXBhbnkubG9jYWwwDQYJKoZIhvcNAQELBQADggIBAEyeENH28LpHCID0A4flab5U +a+1x4t1ChXMFad7ngfpuvLjAv3IYe29TszGM/jFtgqATGsfyModwp6/KoQMSr7r1 +41npXb3mUuio5JmlKDvUr0Z8UemzA9aOn21G/knCLQGoAKMcMI0kS2vW4yOUqW2P +Ewq3Kz8W16f6NNUrmptfShUhIQa72C9eSWDBsmvB2S4WCWmvFspZZz49MpUY12MR +TuF+JaURzBsGpSBhYUNC9p2o5108dePWvHhC/6lGwmt41WwkGVMwU0XcN0hD4OqY +DkwRwZihn5aTbR5LsNqTucdAYEOHURyRrR7Rc49b3AGe52/DRncRN/4T9W/nqvzv +B9BNTfB3Z3Gph9+6o2GpW+jVAqHg25OpZ8Infwq/GfVQNzGa9yfw49ZpRWf0l1L4 +ea+Yw6fh0VQjCheQSBvGO/JmzrhG6jhG+ZqNWo8TVbIXcyXxxA/yCDzMOLwkxYy+ +IN9Gv3r2lEbUiqSfvGDlb+WZOpq1LY2zSesXWGJlprvTxL5rxKUD/Cpd/vLfz7kP +2JPWnYYPeTIJ32updp6M1S6jryd0Hr4P2dm3fKPtFMooR5J6VhXayRORtw5hRhbm +i8J1oJTfxbvqusqTdVlMMDUkv4Afl9AXwNEiIuurNDjMJjCwdAgOOtmNscKtv4rP +yfhtFO2Q8gr60gccsi7F +-----END CERTIFICATE----- diff --git a/demos/cluster/files/certs/conjur-master-2.mycompany.local.key.pem b/demos/cluster/files/certs/conjur-master-2.mycompany.local.key.pem new file mode 100644 index 00000000..9a8979ad --- /dev/null +++ b/demos/cluster/files/certs/conjur-master-2.mycompany.local.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAu5/z55JtZjTRrcjDz/jAd5M7UaAyAmpCDy3u9mDLNAb47+tH +7yloVHagK3qZN4DaaPjuiyw8dPkw3j+eUY9k62JPe2jxfP7Ns23kH0yOaF8Ri84B +oIr0wjvRiR5eQdvDTeq/RGp9jNFZ/oajQcZ+bv66j4eD0YRvGrhLIq86RX/fCm1l +lLIpHaOA8+GcvHF8f3vc5nH9fP0mCwOB/QntpFw9di3rtTlVA9qsGk9imPZCGZ1z +FRuzjedb/1eV+is193032Qoy/0VtoBbKO1OFq+eV5Tfhj+57cWj5c3YM8hctFpOr +7oFKWKF08MGpMEY5E0V7V+q+on0uswd1jwzSDQIDAQABAoIBAQCeoSjE4/8Mh6Gz +jWdIgWawclGXvJorgo0halN8CPAkp7R2m/TwlpC3wKfAuuGplI6Ua8q67gabW0fe +z+jZyiOoAzFyBJMPfBqMFl/luoM4aRBbpCuqAXHYely40m0cv2ILkWpuvJ4znZi5 +4jlLVjf1PfabfRaM4KxS6ffUdlQNBxBaAiDYPxJNt28BE70AJlDbC/EFlDUEfrvS +OSwiVu//EHWBLf/2qM9EfnN7SwKYY4xMwn+efRoWN42wt4VFM6s2pNE2u20RYMLA +tL9n3+SWV2jel6mkEB49ihYHPoV6AGNPwutOxTQummhPN8WWvdYhP2VuQm1ycoFB +1YfN8t7hAoGBAPDued3oB7w8/6xREbg+xHRIh/KUjL2DROHg6kIiA5Su/pSaoRmU +GJCfL4eDhpoqsL1z2iNjOPM1EJR//IBzdK5ALiKdW/Dp1BsqQpc9vkw1FDWCtWjQ +xGZyrnUhXu84vsAVMOtu3C2bEVUDgVEi0Ir2Vt33OVZGAwzBLEgF8dtZAoGBAMdb +/U/EumGCGSguNE/dVw4TdPKWb1g1sOQXqzHlRtNF97GssvSHPWTpORf8fteKoly9 +1JbMs94eOD4Z4IPipCPOwscZPSXKZwEvM9A+uebqB7Qq0x7fGakUCQ61J2Fl6iiw +zKMY4DIJK22ZNbIAKlppzhJW4DFrJXpvA29r/rnVAoGARcldxVgbPXwRtrD4x/xu +XRxRPIOozJAEWMUUNbmyfdO+a/7qIQWTo/hoBQGk8GzjKs0u50crTM8XEVyNIAvR +RVPTyTT5V6vzQzcXeMVqpJpPUzycHVMzQFWBkO3smLBAGFVLCTbgUdlzyMMuJvlF +nKrD+KFOm13GLmCZ2fbW2mkCgYEAuJWrzRfRmkbjFBjzxp6h5B6Pwa0YGwxbZFWl +5OTs1uGJnbDRYSd26OAoRNU8fEWYX1ZEZ/vQ7m/8k0NSZcqLP7xJDB+KRltJVAdo +agAqEGvQBjlAkOzwzWQHnt6MP9olHNfWIYz+yFVFKI0a8lzE2kHs034sxpT2do4j +GB9eEqECgYAeK2bwnmKcQRGntZmG2OmlLbFxc6JUfU6BrXA5BiRw466HPLJKKOFB +/txgE+9DkRUHl0yg1EImqb1zcoSL1yprJ9Ux7oK821piJ5JrTg9gPTcDHBCbxEG5 +zOizOvm5UuqGnrkxK9wTQzb60u5badowo/AgPeCStn1OcBK+6DOPtQ== +-----END RSA PRIVATE KEY----- diff --git a/demos/cluster/files/certs/conjur-master-3.mycompany.local.cert.pem b/demos/cluster/files/certs/conjur-master-3.mycompany.local.cert.pem new file mode 100644 index 00000000..c389f006 --- /dev/null +++ b/demos/cluster/files/certs/conjur-master-3.mycompany.local.cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFGzCCAwOgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYD +VQQLDAZDb25qdXIxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0xODEwMTkx +NjI0NDlaFw0xOTEwMjkxNjI0NDlaMIGEMQswCQYDVQQGEwJVUzEWMBQGA1UECAwN +TWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9uMREwDwYDVQQKDAhDeWJlckFy +azEPMA0GA1UECwwGQ29uanVyMSgwJgYDVQQDDB9jb25qdXItbWFzdGVyLTMubXlj +b21wYW55LmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3w6I +MbGKxyT8aiflT3GTLzCXx+nCmKTXC+N4fGAFt8kD5czVSP9Py2O4AVwp8yyYyuxS +StRNK6DNPuyyotjiflPUBDcb3GEnrG+GW8SOL/+BSficYYniIn3pZpGbaC+3F/hk +rO8WiH3++NHCpYtNxHEBbmv2yBEUijFptxgWeSacgy18saKylupa91D6zOqK64fh +Db7krL5ag7NxHl8IlLMz6PSaw2RIkQINsQHp1kX2I6xJ5VWceh3v93uuhD++p82K +EzDKJYWoc55aSKPFAqsLWQWGSEJBNWQOXS8K+WL5KQY3bqD6/GR/b+2gqqQf21+m +//9A2VohdOgbhuK3VQIDAQABo4G2MIGzMIGwBgNVHREEgagwgaWCH2Nvbmp1ci1t +YXN0ZXItMy5teWNvbXBhbnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItMS5teWNvbXBh +bnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItMi5teWNvbXBhbnkubG9jYWyCH2Nvbmp1 +ci1tYXN0ZXItMy5teWNvbXBhbnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItNC5teWNv +bXBhbnkubG9jYWwwDQYJKoZIhvcNAQELBQADggIBAJk9wFyEIbyyFyN6q5C5UD2I +CteFiw1rWnx1zGX6HyVy0tKCCDmoqudF1dSdym2pR41JyW3EPvYHh4z4vhdIt/+Q +p+4WKem+as6ErWR99X058Hvfew5fXoryqRY0wAyIaol0Bq2GI/EeZw0EnzUsl4dg +JK0iQevyLZkxrQSgQYXKaPUywxsDJwzlKD7pp3VuUsYhaAAOg1w+E2cHA+09jXm8 +Ku1FOePzPBJybwIeWPjr9Z4VkyqsA07j3uH3nFZz4/aDek6gqz5AsCHvt4ZiLJ5C +fb1OV1bwu8zBBKzwA+T5aWVKu9IHikwJym7TXZ+c/sYQRovqHY4frzW7dqlxoguX +fzb7NFW/zgpW2j8gni/YXOHH5HmwiRfUj38VOsCQy8eQQkzkLdMqTb7uzYDEPAZi +CHks2jJMa2vMmMaNOdSilHb/aGd+A1Q43O7PhC7FHfCDStrgM4OE952PivcEmFgg +JHReTGdbJLKzmdIfMT4qxfT8Td3m5UXVBCcPbOkeAyADty5GwNzTHTpBi9JevWIF +pElOo4HRAd5u17rJxiGeza2Mufm3cs8TEldQ7/q/yNb8ORNZpkzykLfd+ENkeY2M +eb8i1Z1mFR/fwY3gjigpnnkQo3pBUIZ4mqyfFR/npmH1hhczy24j97hIa68GJkr2 +fjhmyLj8bm9QjWSd0O8d +-----END CERTIFICATE----- diff --git a/demos/cluster/files/certs/conjur-master-3.mycompany.local.key.pem b/demos/cluster/files/certs/conjur-master-3.mycompany.local.key.pem new file mode 100644 index 00000000..a8a3606e --- /dev/null +++ b/demos/cluster/files/certs/conjur-master-3.mycompany.local.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA3w6IMbGKxyT8aiflT3GTLzCXx+nCmKTXC+N4fGAFt8kD5czV +SP9Py2O4AVwp8yyYyuxSStRNK6DNPuyyotjiflPUBDcb3GEnrG+GW8SOL/+BSfic +YYniIn3pZpGbaC+3F/hkrO8WiH3++NHCpYtNxHEBbmv2yBEUijFptxgWeSacgy18 +saKylupa91D6zOqK64fhDb7krL5ag7NxHl8IlLMz6PSaw2RIkQINsQHp1kX2I6xJ +5VWceh3v93uuhD++p82KEzDKJYWoc55aSKPFAqsLWQWGSEJBNWQOXS8K+WL5KQY3 +bqD6/GR/b+2gqqQf21+m//9A2VohdOgbhuK3VQIDAQABAoIBAHXWOYD3KDd4hJiY +Jv5HI9hkNWr5RUJaovi23Onn2F11Jkf6ZBrCNidesNCXHdpHjxh0rCy352TK+GLr +rJt3NIBETNdFPcS41rqz2CkWt38H3gdz/TlSHFLYbbsv5QevXWyeXqE1VZQZ698L +AWdvJlBG2ti41JBw5Ybz/8MoSIcLMDk9lVEzop8YKqDTy5IQoVo/P9lTqb86bOgK +nDhL+H7KB66iMW+1v12SNZr/UsQZIePbkalBJ9uG9frVI6kPZFgbd7MdJiWAU398 +BYxs3olTg8+ZA3YpYVWIHdYkiHPMIBx2nIkAl1UelKvrqIJjJSVyAFOGC/b1FpeT +go0nxykCgYEA9v6yohY7XKImKIL+5fqd03+6j6rOzfohJp28zQ7g14o3M0IrvEBh +OpHSpd/mqId45B+INyLtQw9iKQs1ObZVwZEzKB5O/Liv1sEXM0+hmd90HrWlKX5t +cLb75dingIz0LdpXdyIHOnPTwGYLLServ5YbkSdAm0NG7TiQOlNu5c8CgYEA5zBo +8PJDU92WWv8bBYgL1G3h+ff6UHB6xkyCTKt6dYUXFXQmhdtRnevjvW6cEBT2/si5 +v8LvF4eynKjY3xYWfbDgNt++SVTUkcxwyOLlmu9/4aCibb3rprmUMAsC6jwC/P3b ++yya7sOG5hc8Z7mZx2KJzIttxgJvj2pVhwRg/ZsCgYBxK0oV0jHow7LQJRU9spLV +8VQ9t3mCDvVZiDSVkBedKosYRV1cp/LkryPhNLGuzkOp4ni7KpmjfEzxmV0N0GmC +g1D5NMnkKYsHzvkeXYIhyqyd1YSTeoYSewT3z0kQMYU/7SbeQw0kzyVapmbAjci3 +w8NlwqJrgWviDWSoFMpfKQKBgE1nIdt54RzVFaAFxVBGyl8nIv+EDOSdpB18RCvT +Rb7O/nmKV9N9KIhNEAS+YbXorwGCxt3zMAWawyw8Q8/9Hy6Z55e3tYfrxPfDkQdR +IDqNcS1jkL5ZVeqOO5USOrmdugpmHB6uQnkqMaIbqXe45kmhLi2ziN9AtYU4vsXj +q219AoGAR0YI4S0+S3Acq1BRDYpYzVzSpdaBwxhT9ct4aXMShAdRxn0UKxq5Q2Ln +uQmvDoRNggdUlpxX4gvvE5700XuUJXEi0RvWc3YNv5hSEFm2oIM2ksEVFFo5jEis +0DRxnHg8gWQzKXeV2P4hYAsLacbve/5hcND9oCYISO0bDl+9Fjg= +-----END RSA PRIVATE KEY----- diff --git a/demos/cluster/files/certs/conjur-master-4.mycompany.local.cert.pem b/demos/cluster/files/certs/conjur-master-4.mycompany.local.cert.pem new file mode 100644 index 00000000..3e13a7d7 --- /dev/null +++ b/demos/cluster/files/certs/conjur-master-4.mycompany.local.cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFGzCCAwOgAwIBAgICEAUwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYD +VQQLDAZDb25qdXIxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0xODEwMTkx +NjI0NTVaFw0xOTEwMjkxNjI0NTVaMIGEMQswCQYDVQQGEwJVUzEWMBQGA1UECAwN +TWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9uMREwDwYDVQQKDAhDeWJlckFy +azEPMA0GA1UECwwGQ29uanVyMSgwJgYDVQQDDB9jb25qdXItbWFzdGVyLTQubXlj +b21wYW55LmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0uiW +Pk7ooGmduLpTyIUsxSx6VmaDrAaacgDCnuZujoRWjGmUzrdZdXZV2KpXupfqBxf/ +L9/KpwA1dDCIMWfjpsE7sciwXJ5taL2v4HhMpQ/Csfjc1Q7cOdNp0PpFqFzCWQhZ +4BZgL5QezQ5sIsWBiCCgRg3Bw9GGb3/wqXk98cEPib//5RzJKmC9XBk3XTsMscTS +i2WQz+cIkSynxGKj6WPgpeT0cH75QCAjRsjB/Jv2ooOz8PUlTUbghk82Qwuk61jt +kni2Nb7Yc7ouOhjtAtfPxiCJMwfE79YlBoYb7L/y6Rdnneg1ooNWEWfJlbU6CcaY +ckG+7CfZOpLRTVvFOwIDAQABo4G2MIGzMIGwBgNVHREEgagwgaWCH2Nvbmp1ci1t +YXN0ZXItNC5teWNvbXBhbnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItMS5teWNvbXBh +bnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItMi5teWNvbXBhbnkubG9jYWyCH2Nvbmp1 +ci1tYXN0ZXItMy5teWNvbXBhbnkubG9jYWyCH2Nvbmp1ci1tYXN0ZXItNC5teWNv +bXBhbnkubG9jYWwwDQYJKoZIhvcNAQELBQADggIBAJ+yPqfR3W0iwxWoN2gU9sSi +XVzGDygdA7qFTUURJuWCGyoKyUFwN3mWaA1nTzzqpglstUcAmRky7rd294T4SWd8 +TWeVywxX58BjoZudX88S0coRvitOwBkp0cFPhowd9zQBeKhR2mQndghebAyO7jag +jpthG+smdZHW7L1JFDbk7/9ES8qyn+ogdO+/U5Ayd5JiD+GdfMMEE9qpRNyLIKUL +2Hd+Du+qNHwXr86O5naWjszLW1XD2rC35OQuqQMkwiYpx9n/NL9ttgRSwFwlVzTb +OCTdO0kWa12NMO5/Ga0M/2XgSJRXpbIPsPz7hm6c4UkibMFazzHBxwHdrW80EOLK +EJFCiB1NenywHio4M3T2VIX0wK8nYRUpnRsr9pXJJ/UC3BMUDHrz/xaJ5GYEyjvg +fpx/YDJZ0RKmBmldWzErCuZv//O/J5O9FOnTiXs4MmbDReC/8XqtGr6gKbmXuOFU +oC5qhktruNDsBJuv32dR/9DjQ4TBJh1nKkt5r4uw9HfTrRP7XymKEoUoV7Fyrier +6SDsp0IpVy9kAfcgEO5Y0jfZRZJY/waWqnmcl2TVT0fOIP4jc0uDa3aJ2eT9VBGF +VudauUkfLNJZqzroBmwzCnDkZVbAKlHkOmpcPq2V2fLFRkEe1SEAhBiU5U94jVPU +EeCbUWXn2NYhfd1uIutk +-----END CERTIFICATE----- diff --git a/demos/cluster/files/certs/conjur-master-4.mycompany.local.key.pem b/demos/cluster/files/certs/conjur-master-4.mycompany.local.key.pem new file mode 100644 index 00000000..d0fbfedb --- /dev/null +++ b/demos/cluster/files/certs/conjur-master-4.mycompany.local.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA0uiWPk7ooGmduLpTyIUsxSx6VmaDrAaacgDCnuZujoRWjGmU +zrdZdXZV2KpXupfqBxf/L9/KpwA1dDCIMWfjpsE7sciwXJ5taL2v4HhMpQ/Csfjc +1Q7cOdNp0PpFqFzCWQhZ4BZgL5QezQ5sIsWBiCCgRg3Bw9GGb3/wqXk98cEPib// +5RzJKmC9XBk3XTsMscTSi2WQz+cIkSynxGKj6WPgpeT0cH75QCAjRsjB/Jv2ooOz +8PUlTUbghk82Qwuk61jtkni2Nb7Yc7ouOhjtAtfPxiCJMwfE79YlBoYb7L/y6Rdn +neg1ooNWEWfJlbU6CcaYckG+7CfZOpLRTVvFOwIDAQABAoIBAQCO2dRxjXbIt+CJ +L0LyTSl+v1p5TOQgTzSqxNMNV1xIkWAhqJ2OyecAxU7t+qqDCsQLW/iPD5AuPtj1 +wq1scUZjOvxYtWqmwPOv/tKyQij/n8YqTzob4P3O+N/yGKG3oGROc3aUbfNmJnga +QYuCna3XaunDqSu1myPoP4rc7u7C39rrLmyFufUP43fgwzz6P0HqvPdfoYbn5hG+ +x5miOrABAeloLHbyBqOja/AjwzWYYdEo4SP2wWHBwLuW5Lrbo7waCDzNnOHJvUIB +yAeuzowJ1V1f1iOEWFDxD2qKHwea26SfUCs/6wW/5Ec257ieQaTnnQkzai2oy2ls +FisDRhXZAoGBAO57Q4C+MFoaO8zd9fG+RXsUwNhTi/YF3NwxHyHL3lXYhgeK1hPP +RSO9tDP1/mcfkqZ6A3xeiJc+zEPM03ieEvrPLMXWM9d7C3nOFQ3btiIKVZY3+BYS +9Y/bpaTYvwp4IZz3QNpsn7O6mboVL7rrrB7FnNxft1AVAIfAfK5usNo/AoGBAOJm +zZu0XfTeXs8NnoBIM7WZxO+BSkCNoOaph9lRukpRp97ZbZ1OdprZ2VXURlMRi1fK +OoKI2Tepx+nouHn/tX7XEuJiwhoz6lCzpcaESV2+X3/VSxvHQGOub9C1dYh9t7tP +JBaVeaJjIl6TOMfrDDJhM4FfDsW5L9RTbmt7Y/4FAoGACKZN33iGdm4nJxoR1o/J +I1qwV+hH1keGKDJb57TmPoTY76MYeqV044P46j2M2Z6qigE46STgnWO4sujV7rUF +CTXEcPSA8trSortXxiXm6DspuYYUKHDNmUclLeJyo2WSCohpQMLZ1AH7m2UzUvtD +ReZy9wc9tdjdKQ9RNl5raa8CgYAfjrLUJEUAb8qJU92nBelnQ8LGm5/s9ZDa9gCA +kzrDRzR+BJKZ3aj8lqcLpqYSyBxDJWYYcdjNQHYkLZMhNjpnLrVsJtXlbx0XGKNf +02qijXmkSOfKPHDGNDdTwSdb2iI1Eqf2Gem1b9oHkr/UZffyQcg7HTPi7Zg0IVj/ +1FgwvQKBgCSm3Nrg5VFacuJ9MwLhfM6SPPxeuf7tT4Lti/bQFZK1X3/jPMg/WrCJ +L8idnT7M18CfAwxL79A8bk7LZbutIfTFJDWPuUsBwyJvw4NP6K//WWTBlLElS+OA +H71rbyjndWVhdCSwTcbU14TfmJCVwLh5eRY/P8/OUWg5B/lKy4uE +-----END RSA PRIVATE KEY----- diff --git a/demos/cluster/files/certs/conjur-master.mycompany.local.cert.pem b/demos/cluster/files/certs/conjur-master.mycompany.local.cert.pem new file mode 100644 index 00000000..22437c4e --- /dev/null +++ b/demos/cluster/files/certs/conjur-master.mycompany.local.cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEpjCCAo6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYD +VQQLDAZDb25qdXIxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0xODEwMTYx +MjE0NDdaFw0xOTEwMjYxMjE0NDdaMIGCMQswCQYDVQQGEwJVUzEWMBQGA1UECAwN +TWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9uMREwDwYDVQQKDAhDeWJlckFy +azEPMA0GA1UECwwGQ29uanVyMSYwJAYDVQQDDB1jb25qdXItbWFzdGVyLm15Y29t +cGFueS5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMedSw3v +4v9Ml35LAIQyJUlurbmBPXjFitCJLAsN8TPOJIEjI5zADGBU/bh4jJp4OXeMzVqu +Oji8NKgJv6uZHLEXZbssfJzdVj2neEqY0P+jN6dWT+HOlhn3P324oUzwwFoyaUBj +CPQMAsHxey2yxPzAvA0UjYbuhyTri+d9KtO5KyDhm1eF/cM6GMO/XOxGtrpjzfbU +EFlomRP7E/6C2S7GfgMIUEmjT9jMCGRhTz+JHYL1ivK/iVsCuLzmUp90/FfhBmI2 +M6fmJQ1+pkSgioFiCjkiWrApzy6hfngXaLJsURMnx/SAG+I+L/CrmI/sRfE7Ao1h +BeMi3hF8MumgfjECAwEAAaNEMEIwQAYDVR0RBDkwN4IdY29uanVyLW1hc3Rlci5t +eWNvbXBhbnkubG9jYWyCFm1hc3Rlci5teWNvbXBhbnkubG9jYWwwDQYJKoZIhvcN +AQELBQADggIBAFSavCBQXyIfxMxpro5Vz7fPsgirM423P26nx7lRup4C+mT8d+1W +caZdeSJuaa46jNRVfQ92B0Mchi51PuyjmJpO2V+TH9QNqhmVLB+nMS8XyMRFO0zu +vTa9MLzvd7aRGIUB3MDrGGeeQJ57EA5nMrenjEE370SPsMK2ZUk1E2Kw3hd4A4nk +LHHD4fUUgsyIROghdsIZupOmsg63ZFZ+Sbt8koN8u1ToB6oFs39wnKxggA659qPO +UtvNI+BBwNgmi0zVSweh+8bGI1SL7zD+jswxekz3BujKVUfbGceYvVvEEy9vLrlN +jl4f5wumMvKX5kOBiVhZ+rHGm2YPNTVmrwuIyL9sPaCokiyOzNW0WzDrtBlnudu6 +Ej59gHdDKafM31iRUEIY3koozEtPi6VxzyhwFB8PISxKSzojkeaIwa0qnnhwzgIO +GA72LMZJytdt8lisVIvwPu2f33mXQmZAz5MOONH0lIj3e+Hna5uPNX2OmAGF1PvW +7XSVcL0lxKR4bdwKclzWGO3fWk47eXHFyoUBhKM538DENNAXut3eD0TY7RdmGfyy +Wj6/yc0tsx5MHnf4L0xWjZUqQB7jpfj5WOosmw/xwMyRWheAQxelo++ulZTqOs8W +OgmkqQaJyJNaXPne6VO0r46kWJxst+Ua4Xtf6m36xkKQWb5OpxmaOmwR +-----END CERTIFICATE----- diff --git a/demos/cluster/files/certs/conjur-master.mycompany.local.key.pem b/demos/cluster/files/certs/conjur-master.mycompany.local.key.pem new file mode 100644 index 00000000..0fb705ea --- /dev/null +++ b/demos/cluster/files/certs/conjur-master.mycompany.local.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAx51LDe/i/0yXfksAhDIlSW6tuYE9eMWK0IksCw3xM84kgSMj +nMAMYFT9uHiMmng5d4zNWq46OLw0qAm/q5kcsRdluyx8nN1WPad4SpjQ/6M3p1ZP +4c6WGfc/fbihTPDAWjJpQGMI9AwCwfF7LbLE/MC8DRSNhu6HJOuL530q07krIOGb +V4X9wzoYw79c7Ea2umPN9tQQWWiZE/sT/oLZLsZ+AwhQSaNP2MwIZGFPP4kdgvWK +8r+JWwK4vOZSn3T8V+EGYjYzp+YlDX6mRKCKgWIKOSJasCnPLqF+eBdosmxREyfH +9IAb4j4v8KuYj+xF8TsCjWEF4yLeEXwy6aB+MQIDAQABAoIBACYDDgfZZqC3NSIX +pkGGSxNwwCRTOCGHfKe5d2mjfgsfdlQhHOb8q16s0KQQULYZrtfVOEXMZ8nmDSDy +uk0zGwOeMQEzt4cnnwSen4mVEDeeHTsAdLXLYUoQi0alohHExtxmPSTFty7CGsRT +9+D76gc3rJfREiJfydx9/mZWr5Ehm1nUMtWguFyfVxuvOv11mwJZDeQ+gR4+Mpzu +n0M+GA2la8c0OMtAPZ8VjvYbchseFO+qP+thJLzF1m17X5qDwh+vpoU3lB1Kd/w4 +1iYq0IUL5oVjogyyH+jbkRgUqHcd/3NIOybu0vmPCiuj84Ddt0S8Znq93JWWVjEE +fYj0MAECgYEA+HninBXUBTpBv+B0eMDoHlGL5PeKJswmzBlbKe30E7mJmizY+tCg +J10RQoFEXG3P5cKr5z5QYi9UosmhLi3oVY9hIx5OR6seC78c7n+I0r39FvGefewH +b18/i6aoQGCkRv4F/XDy1Pxuec3ot/T6KNJa7DMPL7opAHFzaiKYB5kCgYEAzail +dy2aDZg83ZW0w764rZRpTNO2HCl/KFHm4npLQe9hyKo0lc/NJocmyuYugMwj4iLE +EYm+54qkgIyBQ4CT8OMMO3Pc5k7cquRaxuNEi3Va3etozAVciURRAYM0EcKNJ+xG +6Q3Zi6YZJyXA7PptriMRFojV8/S7Q9/QsN706lkCgYAX8U63sZbDhjCNt6ghdp0n +Rr5PKtciE+vtIMhbCvXI7MjolUe3K2EzSdF+8gvPSDmPLyn3V1bRjzP9l6YzV/Ma +Q32dr67lUwTLJvg3twxNGkeH7XJTOeohfjEWWNG/mlBaEuIq4LZVdZmDnSa+ixmL +03E1b1oYRDztMQFpCbpSiQKBgGMo0HcxHpk1cQtp9ll3KPZQm6D2Z1UW0P+w1cEX +NBgbgqtNHcOqCQFtos+rwnpJc3fCSYUnREvBtmVg2aahZTN9VdWInNbS6WTga8B/ +rfoL4H8l1UahwydQMDqpdz6k7oh0TRBrpBvIP1J3ypi4eo++yqtx2K8irfQhAy90 +oOQpAoGBANBe9yqwplaB1GHb+uC+m3suTB2tbZvjxzVTQcWsfpOtwl6SrUbKgkTj +F4w1fg9ej2ag6+B+yQDe53DpVTTGo0l4VYIrlrJamwYFb5mNPsi4ixgTuvXZgU5Z +UKoJPx1jw91EkYB3+2mhTLJtghm8cyo+vfDRRyjHk2sJw6jdYKH1 +-----END RSA PRIVATE KEY----- diff --git a/demos/cluster/files/haproxy/haproxy-bu.cfg b/demos/cluster/files/haproxy/haproxy-bu.cfg new file mode 100644 index 00000000..b999c808 --- /dev/null +++ b/demos/cluster/files/haproxy/haproxy-bu.cfg @@ -0,0 +1,42 @@ +global + maxconn 100 + +defaults + log global + mode tcp + retries 2 + timeout client 30m + timeout connect 4s + timeout server 30m + timeout check 5s + +listen stats + mode http + bind *:7000 + stats enable + stats uri / + +frontend conjur + bind *:443 + # bind *:5432 + # bind *:1999 + default_backend nodes + +backend nodes + option httpchk GET /health + option forwardfor + http-request set-header X-Forwarded-Port %[dst_port] + http-request add-header X-Forwarded-Proto https if { ssl_fc } + server conjur-master-1 conjur-master-1.mycompany.local:443 check ssl verify none + server conjur-master-2 conjur-master-2.mycompany.local:443 check ssl verify none + +# listen postgres +# bind *:5432 +# option pgsql-check user healcheckuser + # option httpchk + # http-check expect status 200 + # default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions +# server conjur-master-1 conjur-master-1.mycompany.local:5432 check +# server conjur-master-2 conjur-master-2.mycompany.local:5432 check + # server conjur-master-3 conjur-master-3.mycompany.local:5432 + # server conjur-master-4 conjur-master-4.mycompany.local:5432 diff --git a/demos/cluster/files/master-key b/demos/cluster/files/master-key new file mode 100644 index 00000000..1c73f8e9 --- /dev/null +++ b/demos/cluster/files/master-key @@ -0,0 +1 @@ +êˆSÝ-HÓ;e´É$ì¸ «öƒ9­øz×ËÛ忪"3 \ No newline at end of file diff --git a/demos/cluster/policy/application_grants.yml b/demos/cluster/policy/application_grants.yml new file mode 100644 index 00000000..be297703 --- /dev/null +++ b/demos/cluster/policy/application_grants.yml @@ -0,0 +1,4 @@ +# Grant the team_leads permission to read+write the "myapp" variables in production +- !grant + member: !group developers + role: !group staging/myapp/secrets-users diff --git a/demos/cluster/policy/apps/myapp.yml b/demos/cluster/policy/apps/myapp.yml new file mode 100644 index 00000000..419c857c --- /dev/null +++ b/demos/cluster/policy/apps/myapp.yml @@ -0,0 +1,47 @@ +- !policy + id: myapp + body: + - &variables + - !variable + id: database/username + annotations: + description: Application database username + - !variable + id: database/password + annotations: + description: Application database password + - !variable + id: stripe/private_key + annotations: + description: Stripe API key + - !variable "foo bar" + + - !layer + + - !host-factory + layer: [ !layer ] + + - !group secrets-users + - !group secrets-managers + + # secrets-users can read and execute + - !permit + resource: *variables + privileges: [ read, execute ] + role: !group secrets-users + + # secrets-managers can update (and read and execute, via role grant) + - !permit + resource: *variables + privileges: [ update ] + role: !group secrets-managers + + # secrets-managers has role secrets-users + - !grant + member: !group secrets-managers + role: !group secrets-users + + # Application layer has the secrets-users role + - !grant + member: !layer + role: !group secrets-users diff --git a/demos/cluster/policy/cluster.yml b/demos/cluster/policy/cluster.yml new file mode 100644 index 00000000..af29354d --- /dev/null +++ b/demos/cluster/policy/cluster.yml @@ -0,0 +1,12 @@ +- !policy + id: cluster/conjur + body: + - !layer + - &hosts + - !host conjur-master-1.mycompany.local + - !host conjur-master-2.mycompany.local + - !host conjur-master-3.mycompany.local + - !host conjur-master-4.mycompany.local + - !grant + role: !layer + member: *hosts diff --git a/demos/cluster/policy/hosts.yml b/demos/cluster/policy/hosts.yml new file mode 100644 index 00000000..4496efc9 --- /dev/null +++ b/demos/cluster/policy/hosts.yml @@ -0,0 +1 @@ +- !host test-host-1 diff --git a/demos/cluster/policy/policy.yml b/demos/cluster/policy/policy.yml new file mode 100644 index 00000000..17a09ae6 --- /dev/null +++ b/demos/cluster/policy/policy.yml @@ -0,0 +1,11 @@ +# Top-level policy file + +# Define "staging" namespace, owned by the "team_leads" +- !policy + id: staging + owner: !group team_leads + +# Define "production" namespace, owned by the "security_ops" team +- !policy + id: production + owner: !group security_ops diff --git a/demos/cluster/policy/root.yml b/demos/cluster/policy/root.yml new file mode 100644 index 00000000..d14b257c --- /dev/null +++ b/demos/cluster/policy/root.yml @@ -0,0 +1,2 @@ +- !policy + id: conjur diff --git a/demos/cluster/policy/users.yml b/demos/cluster/policy/users.yml new file mode 100644 index 00000000..ddf4b093 --- /dev/null +++ b/demos/cluster/policy/users.yml @@ -0,0 +1,72 @@ +- !group security_ops +- !group team_leads +- !group developers + +- !user + id: jason.vanderhoof + annotations: + first_name: Jason + last_name: Vanderhoof + email: jason.vanderhoof@cyberark.com + +- !user + id: marcel.calisto + annotations: + first_name: Marcel + last_name: Calisto + email: marcel.calisto@cyberark.com + +- !user + id: ernest.alvin + annotations: + first_name: Ernest + last_name: Alvin + email: ernest.alvin@cyberark.com + +- !user + id: victoria.nandita + annotations: + first_name: Victoria + last_name: Nandita + email: victoria.nandita@cyberark.com + +- !user + id: sophie.madelon + annotations: + first_name: Sophie + last_name: Madelon + email: sophie.madelon@cyberark.com + +- !user + id: terrance.blake + annotations: + first_name: Terrance + last_name: Blake + email: terrance.blake@cyberark.com + +- !grant + role: !group developers + members: + - !user marcel.calisto + - !user ernest.alvin + - !user sophie.madelon + +- !grant + role: !group team_leads + members: + - !user jason.vanderhoof + - !user victoria.nandita + +- !grant + role: !group security_ops + members: + - !user terrance.blake + +# Grant the less-powerful groups to the more-powerful groups +- !grant + member: !group team_leads + role: !group developers + +- !grant + member: !group security_ops + role: !group team_leads diff --git a/demos/cluster/start b/demos/cluster/start new file mode 100755 index 00000000..b3dd0614 --- /dev/null +++ b/demos/cluster/start @@ -0,0 +1,234 @@ +#!/bin/bash -ex + +function print_help() { + cat << EOF + +Provisions a Conjur cluster locally, using Docker. + +Usage: start [options] + + --auto-failover Configures the cluster for auto-failover + --custom-certs Installs custom certificates from the "files/certs" folder + --disaster-recovery Configures the cluster with a single Disaster Recovery node (only if the cluster is Auto-Failover) + -h, --help Shows this help message. + --load-data Loads sample policy along once th cluster + --master-key Encrypts certificates using a master key + -t, --tag Starts a cluster with a particular appliance (defaults to 5.0-stable) + +EOF + exit +} + +# Determine which extra services should be loaded when working with authenticators +# export VERSION=5.2.2-20181029194559-7305fae +TAG=5.0-stable +AUTO_FAILOVER=false +LOAD_DATA=false +MASTER_KEY=false +CUSTOM_CERTS=false +DISASTER_RECOVERY=false +while true ; do + case "$1" in + --auto-failover ) AUTO_FAILOVER=true ; shift ;; + --custom-certs ) CUSTOM_CERTS=true ; shift ;; + --disaster-recovery ) DISASTER_RECOVERY=true ; shift ;; + --load-data ) LOAD_DATA=true ; shift ;; + --master-key ) MASTER_KEY=true ; shift ;; + -t | --tag ) shift ; TAG=$1 ; shift ;; + -h | --help ) print_help ; shift ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac +done + +export VERSION=$TAG + +# if [[ $AUTO_FAILOVER = true ]]; then +# docker-compose up -d --no-deps conjur-master-1.mycompany.local \ +# conjur-master-2.mycompany.local \ +# conjur-master-3.mycompany.local \ +# conjur-master-4.mycompany.local \ +# conjur-follower.mycompany.local +# else + docker-compose up -d --no-deps conjur-master-1.mycompany.local \ + conjur-master-2.mycompany.local \ + conjur-master-3.mycompany.local \ + conjur-follower.mycompany.local +# fi + +docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke configure master \ + --accept-eula \ + --hostname conjur-master.mycompany.local \ + --master-altnames conjur-master-1.mycompany.local,conjur-master-2.mycompany.local,conjur-master-3.mycompany.local \ + --admin-password MySecretP@ss1 demo +" + +docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke seed standby conjur-master-2.mycompany.local conjur-master-1.mycompany.local > /opt/cyberark/dap/seeds/standby-seed-1.tar + evoke seed standby conjur-master-3.mycompany.local conjur-master-1.mycompany.local > /opt/cyberark/dap/seeds/standby-seed-2.tar + evoke seed follower conjur-follower.mycompany.local conjur-follower-1.mycompany.local conjur-master-1.mycompany.local > /opt/cyberark/dap/seeds/follower-seed.tar +" + +# Setup standby 1 +docker-compose exec conjur-master-2.mycompany.local bash -c " + evoke unpack seed /opt/cyberark/dap/seeds/standby-seed-1.tar + evoke configure standby +" + +# Setup standby 2 +docker-compose exec conjur-master-3.mycompany.local bash -c " + evoke unpack seed /opt/cyberark/dap/seeds/standby-seed-2.tar + evoke configure standby +" + +docker-compose exec conjur-master-1.mycompany.local bash -c " + evoke replication sync start +" + +docker-compose exec conjur-follower.mycompany.local bash -c " + evoke unpack seed /opt/cyberark/dap/seeds/follower-seed.tar + evoke configure follower +" + + +# if [[ $AUTO_FAILOVER = true ]]; then +# ./cli conjur policy load --replace root policy/root.yml +# ./cli conjur policy load conjur policy/cluster.yml +# fi + +# if [[ $CUSTOM_CERTS = true ]]; then +# docker-compose exec conjur-master-1.mycompany.local bash -c " +# evoke ca import -r /conjur_files/certs/ca-chain.cert.pem +# evoke ca import -k /conjur_files/certs/conjur-master-1.mycompany.local.key.pem -s /conjur_files/certs/conjur-master-1.mycompany.local.cert.pem +# evoke ca import -k /conjur_files/certs/conjur-master-2.mycompany.local.key.pem /conjur_files/certs/conjur-master-2.mycompany.local.cert.pem +# evoke ca import -k /conjur_files/certs/conjur-follower.mycompany.local.key.pem /conjur_files/certs/conjur-follower.mycompany.local.cert.pem +# " +# if [[ $AUTO_FAILOVER = true ]]; then +# docker-compose exec conjur-master-1.mycompany.local bash -c " +# evoke ca import -k /conjur_files/certs/conjur-master-3.mycompany.local.key.pem /conjur_files/certs/conjur-master-3.mycompany.local.cert.pem +# evoke ca import -k /conjur_files/certs/conjur-master-4.mycompany.local.key.pem /conjur_files/certs/conjur-master-4.mycompany.local.cert.pem +# " +# fi +# fi + +# if [[ $AUTO_FAILOVER = true && $CUSTOM_CERTS = false ]]; then +# docker-compose exec conjur-master-1.mycompany.local bash -c " +# evoke ca issue conjur-master-2.mycompany.local +# evoke ca issue conjur-master-3.mycompany.local +# evoke ca issue conjur-master-4.mycompany.local +# " +# fi + +# if [[ $CUSTOM_CERTS = false ]]; then +# docker-compose exec conjur-master-1.mycompany.local bash -c " +# evoke ca issue conjur-follower.mycompany.local +# " +# fi + +# if [[ $MASTER_KEY = true ]]; then +# docker-compose exec conjur-master-1.mycompany.local bash -c " +# evoke keys encrypt /conjur_files/master-key +# evoke keys unlock /conjur_files/master-key +# sv start conjur +# /opt/conjur/evoke/bin/wait_for_conjur +# " +# fi + +# if [[ $AUTO_FAILOVER = true ]]; then +# docker-compose exec conjur-master-1.mycompany.local bash -c " +# evoke seed standby conjur-master-3.mycompany.local conjur-master-1.mycompany.local > /opt/conjur/backup/standby-seed-3.tar +# evoke seed standby conjur-master-4.mycompany.local conjur-master-1.mycompany.local > /opt/conjur/backup/standby-seed-4.tar +# " +# fi + + +# if [[ $MASTER_KEY = true ]]; then +# docker-compose exec conjur-master-2.mycompany.local bash -c " +# evoke keys exec -m /conjur_files/master-key -- evoke configure standby +# " +# else +# docker-compose exec conjur-master-2.mycompany.local bash -c " +# evoke configure standby +# " +# fi + +# # Setup standby 1 +# docker-compose exec conjur-master-3.mycompany.local bash -c " +# evoke unpack seed /opt/conjur/backup/standby-seed.tar +# evoke configure standby +# " + +# if [[ $AUTO_FAILOVER = true ]]; then +# # Setup the standby 2 +# docker-compose exec conjur-master-3.mycompany.local bash -c " +# evoke unpack seed /opt/conjur/backup/standby-seed-3.tar +# " +# if [[ $MASTER_KEY = true ]]; then +# docker-compose exec conjur-master-3.mycompany.local bash -c " +# evoke keys exec -m /conjur_files/master-key -- evoke configure standby +# " +# else +# docker-compose exec conjur-master-3.mycompany.local bash -c " +# evoke configure standby +# " +# fi + # + # # Setup the standby 3 + # docker-compose exec conjur-master-4.mycompany.local bash -c " + # evoke unpack seed /opt/conjur/backup/standby-seed-4.tar + # " + # if [[ $MASTER_KEY = true ]]; then + # docker-compose exec conjur-master-4.mycompany.local bash -c " + # evoke keys exec -m /conjur_files/master-key -- evoke configure standby + # " + # else + # docker-compose exec conjur-master-4.mycompany.local bash -c " + # evoke configure standby + # " + # fi + + + # if [[ $DISASTER_RECOVERY = true ]]; then + # docker-compose exec conjur-master-4.mycompany.local bash -c " + # evoke replication sync disable + # " + # fi + + # docker-compose exec conjur-master-1.mycompany.local bash -c " + # evoke cluster enroll -n conjur-master-1.mycompany.local conjur + # " + # docker-compose exec conjur-master-2.mycompany.local bash -c " + # evoke cluster enroll -n conjur-master-2.mycompany.local -m conjur-master-1.mycompany.local conjur + # " + # docker-compose exec conjur-master-3.mycompany.local bash -c " + # evoke cluster enroll -n conjur-master-3.mycompany.local -m conjur-master-1.mycompany.local conjur + # " +# if [[ $DISASTER_RECOVERY = false ]]; then +# docker-compose exec conjur-master-4.mycompany.local bash -c " +# evoke cluster enroll -n conjur-master-4.mycompany.local -m conjur-master-1.mycompany.local conjur +# " +# fi +# fi + +# Setup the follower +# docker-compose exec conjur-follower.mycompany.local bash -c " +# evoke unpack seed /opt/conjur/backup/follower-seed.tar +# " +# if [[ $MASTER_KEY = true ]]; then +# docker-compose exec conjur-follower.mycompany.local bash -c " +# evoke keys exec -m /conjur_files/master-key -- evoke configure follower +# " +# else +# docker-compose exec conjur-follower.mycompany.local bash -c " +# evoke configure follower +# " +# fi + +rm -rf cli_cache +if [[ $LOAD_DATA = true ]]; then + ./cli conjur policy load root policy/users.yml + ./cli conjur policy load root policy/policy.yml + ./cli conjur policy load staging policy/apps/myapp.yml + ./cli conjur policy load production policy/apps/myapp.yml + ./cli conjur policy load root policy/application_grants.yml +fi diff --git a/demos/cluster/stop b/demos/cluster/stop new file mode 100755 index 00000000..45ee6ea0 --- /dev/null +++ b/demos/cluster/stop @@ -0,0 +1,5 @@ +#!/bin/bash -ex + +docker-compose down -v + +rm -rf cli_cache diff --git a/demos/java-api-client/Dockerfile b/demos/java-api-client/Dockerfile new file mode 100644 index 00000000..82773403 --- /dev/null +++ b/demos/java-api-client/Dockerfile @@ -0,0 +1,9 @@ +FROM maven:3-openjdk-8 +MAINTAINER Cyberark Inc. + +ADD . . + +RUN mvn install + +ENTRYPOINT ["java", "-jar", "ConjurJavaClient-1.0-SNAPSHOT-with-dependencies.jar"] + diff --git a/demos/java-api-client/README.md b/demos/java-api-client/README.md new file mode 100644 index 00000000..bae227ed --- /dev/null +++ b/demos/java-api-client/README.md @@ -0,0 +1,8 @@ +Instructions for building java client +------------------------------------- + +For compiling java test application please run: ./build.sh +Java SDK API fat jar will appear in the directory and docker image of the client application will be available +In addition, JAVA API SDK fat jar will be installed in local maven repository and will be usable for other applications +For Running this application on openshift please look for instructions in ../openshift-install/README.txt + diff --git a/demos/java-api-client/build.sh b/demos/java-api-client/build.sh new file mode 100755 index 00000000..22f11d12 --- /dev/null +++ b/demos/java-api-client/build.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -e +#set -x + +function validate_app { + APPNAME=$1 + CHECK_APP=$( which $APPNAME ) + if [ -z "$CHECK_APP" ] + then + echo "Please install $APPNAME" + exit 1 + fi +} + +validate_app git +validate_app docker + +COMMAND=$0 +echo "$COMMAND" +suffix="/build.sh"; +HOME_DIR=${COMMAND%$suffix}; +pushd $HOME_DIR + +echo "Creating docker image of Conjur Java Client Example" +docker build -f Dockerfile -t conjur-java-client . + +docker images | grep conjur-java-client + diff --git a/demos/java-api-client/pom.xml b/demos/java-api-client/pom.xml new file mode 100644 index 00000000..a19c885d --- /dev/null +++ b/demos/java-api-client/pom.xml @@ -0,0 +1,97 @@ + + + 4.0.0 + + 3.0.3 + + com.cyberark.example + ConjurJavaClient + 1.0-SNAPSHOT + + + com.cyberark.conjur.api + conjur-api + 3.0.3 + + + + + maven-compiler-plugin + 3.10.1 + + 1.6 + 1.6 + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M7 + + + ${env.CONJUR_ACCOUNT} + ${env.CONJUR_APPLIANCE_URL} + ${env.CONJUR_AUTHN_LOGIN} + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + with-dependencies + true + + + com.cyberark.example.JavaClient + + + META-INF/cxf/bus-extensions.txt + + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0 + + + enforce-versions + + enforce + + + + + 3.2.5 + + + 1.6 + + + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.11.0 + + + + diff --git a/demos/java-api-client/src/main/java/com/cyberark/example/JavaClient.java b/demos/java-api-client/src/main/java/com/cyberark/example/JavaClient.java new file mode 100644 index 00000000..f8135125 --- /dev/null +++ b/demos/java-api-client/src/main/java/com/cyberark/example/JavaClient.java @@ -0,0 +1,62 @@ +package com.cyberark.example; + +import com.cyberark.conjur.api.Conjur; +import com.cyberark.conjur.api.Token; + +import java.io.FileOutputStream; +import java.io.PrintWriter; + +import java.io.File; +import java.nio.file.Paths; + +public class JavaClient { + + private static String truststoreFileName = "/run/conjur/truststore.jks"; + + private static void initialize() + { + System.setProperty("javax.net.ssl.trustStore", truststoreFileName); + System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); + System.setProperty("CONJUR_ACCOUNT", System.getenv("CONJUR_ACCOUNT")); + if (System.getenv("CONJUR_AUTHN_LOGIN") != null) + { + System.setProperty("CONJUR_AUTHN_LOGIN", System.getenv("CONJUR_AUTHN_LOGIN")); + } + System.setProperty("CONJUR_APPLIANCE_URL", System.getenv("CONJUR_APPLIANCE_URL")); + } + + private static void enterPending() + { + try + { + Thread.sleep(500000); + } + catch (Exception e) + { + System.out.println("Timer Exception:" + e); + } + } + + public static void main(String args[]) + { + System.out.println("Running Conjur Java SDK Example"); + initialize(); + Token token = null; + try + { + System.out.println("CONJUR_AUTHN_TOKEN_FILE = " + System.getenv("CONJUR_AUTHN_TOKEN_FILE")); + token = Token.fromFile(Paths.get(System.getenv("CONJUR_AUTHN_TOKEN_FILE"))); + } + catch (Exception e) + { + System.out.println("Exception:" + e); + return; + } + System.out.println("Create Conjur API Instance"); + Conjur conjur = new Conjur(token); + String secret = conjur.variables().retrieveSecret("variables/mypassword"); + System.out.println("Retrieved secret = " + secret); + enterPending(); + } + +} diff --git a/demos/ldap-integration/.gitignore b/demos/ldap-integration/.gitignore new file mode 100644 index 00000000..0c78e84f --- /dev/null +++ b/demos/ldap-integration/.gitignore @@ -0,0 +1 @@ +policy/ldap-sync*.yml diff --git a/demos/ldap-integration/README.md b/demos/ldap-integration/README.md new file mode 100644 index 00000000..9c1d8515 --- /dev/null +++ b/demos/ldap-integration/README.md @@ -0,0 +1,40 @@ +# LDAP Integration Demo +This script configures a Conjur cluster with a master and follower. The Conjur cluster +is integration with LDAP using LDAP sync and authentication over SSL. + +This script does not configure a high availability cluster. + +### Requirements + +To run this demo, you'll need the following installed: + +- Docker +- Docker Composes +- Access to the Conjur Docker repository (or the Conjur Appliance Image locally) +- Bash + +### Provision a Cluster + +To view all options available, run the following: + +``` +$ ./start --help + +Provisions a Conjur cluster locally, using Docker. + +Usage: start [options] + + -h, --help Shows this help message. + +``` + +#### Basic + +To stand up a simple cluster, without Master Key encryption, custom certificates, or sample data, run: +``` +$ ./start +``` + +### Logging into your Cluster +Navigate to [localhost](https://localhost) and login with the LDAP username: `alice` +and the password: `alice`. diff --git a/demos/ldap-integration/certs/.gitkeep b/demos/ldap-integration/certs/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/demos/ldap-integration/certs/ca-chain.crt b/demos/ldap-integration/certs/ca-chain.crt new file mode 100644 index 00000000..e3c760c8 --- /dev/null +++ b/demos/ldap-integration/certs/ca-chain.crt @@ -0,0 +1,133 @@ +-----BEGIN CERTIFICATE----- +MIIFzjCCA7agAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwdjELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcMBk5ld3RvbjERMA8GA1UE +CgwIQ3liZXJBcmsxDzANBgNVBAsMBkNvbmp1cjEaMBgGA1UEAwwRSW50ZXJtZWRp +YXRlIENBIDIwHhcNMTgxMTE5MTgzMTE5WhcNMjgxMTE2MTgzMTE5WjB2MQswCQYD +VQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9u +MREwDwYDVQQKDAhDeWJlckFyazEPMA0GA1UECwwGQ29uanVyMRowGAYDVQQDDBFJ +bnRlcm1lZGlhdGUgQ0EgMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +APOYl9GsKxmrErCZI7QI/r+a8i0FUX69rDwFgzutYqLAnRgwYK1ECBb8UPnRmjyg +56ejJAkcruEDYcsgoe+AT/5mIjnOOyC3HsNVKPxVSBkHdZFAxcHS6LG7IX8GUi0+ +YcruiGQvViP3S66hzn4t3T7s/N9HRccVA85v0Lt7QMU8XuwKmmTuDxwuPH3kzNXr +oCccsA2hZomkeTZV2cIUhpuxsSRY2MAo7zwL+zwQ0SWnSH44RyMMhfHQMeKH47Yi +5gKytuadfc+WCpoQv3qQdV52gOXg3ciIrXVwlXriknqOavpGPawg76Ni8LV3LkiZ +QCjsANcGPSLhdlYKsx6tL3siKR9VStiOAfA5pd/o4BwD+2DmMLGKMczfJ9RF5xYZ +hoYKu3wLZTaD0c+wkjDlNDx1CNuJk8USS9TcNHL+w42YFDRyfuTVuGk2na2OJyjC +IDQSo+d2bXTDjWhxy5MjCRC/zxfvgE4jESMKuGVfHBYCK+Y0359yFZG0bi6xSAv0 +sCqNxNLx5TD8oO7GSyN2tBeUaTQn/VcaXd/IHjjRdWwXqgKy9uEazaCxQDliy51I +dT7Dj5WB+pr9WjbIzYX1H6UOVHRJEAsO4F4UcVhiyPLpRCxr1zU6nZNrwZht1yHj +KE8/1Wd5dyAu/vvXmwJxHfhMvojnQiOUBD+wpc3kh9FpAgMBAAGjZjBkMB0GA1Ud +DgQWBBSqXKor7fvfj42WcwZLU20aha+8NDAfBgNVHSMEGDAWgBRf+xqIWDjEYwSL +35LQh/Ttmb8yEjASBgNVHRMBAf8ECDAGAQH/AgEUMA4GA1UdDwEB/wQEAwIBhjAN +BgkqhkiG9w0BAQsFAAOCAgEADx33v583iXqQ+88yiK23NhjEyGQ0yztyw+VnbDLk +G295QMGaset8e5JDuYwgoeINHYMKXBBZQjBqKQKCGdbSyiYovymzTelnukgXwOJg +X7flfR+0YiIG1SpwKwG3vpQy4KRdyDFwab733PW15NMSBN9bm4TmYGR1PqL4Gwrv +xsEpUsxIWwJZwHPcBxYUiXFHFf+M9LTGHuWn2DJdDpEQ3OObje5pPyC9TqCXh2ri +9U0YoS28nBLr8MTXMaBt9Mj/54rFc+1IRQ21u86WPa1QDkHYzjHMZTfDPreQxiSF +bs4ZVyzbklWupdoMsEIUlPHcH4fy03m2WS06vgf6K9H1IUeujyqApilH9RWERHwB +Vt2wTwy2+/YZqsZPFKWeWxr71er3tQyqcTHiNDf92o1anPBAHRnt29rQ07UqSynM +TehAcATLDbLJh8igxdZefMV8gn6/z4gM+auLkchRVCTOnhKexnRfO9gFZCAC99Um +FDVQKRcjxuMDRw75rhSzCvr1+p6uNMjfobURWbuKHOYzXgi1NVG9c/HLwuMMhKLn +s8gGmnjptBKq2BWtnY5+rkpjAGl5zKyR5bV60makcydz7NaAK+WhLI67YZ/2vdyV +zPnx0jDG7G5wP9wT3eXiMKqmdpYNfyoo04M0+feev25yJ5wnfAbThf5rhzcbCHjo +vrY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFzjCCA7agAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwdjELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcMBk5ld3RvbjERMA8GA1UE +CgwIQ3liZXJBcmsxDzANBgNVBAsMBkNvbmp1cjEaMBgGA1UEAwwRSW50ZXJtZWRp +YXRlIENBIDEwHhcNMTgxMTE5MTgzMTA4WhcNMjgxMTE2MTgzMTA4WjB2MQswCQYD +VQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVzZXR0czEPMA0GA1UEBwwGTmV3dG9u +MREwDwYDVQQKDAhDeWJlckFyazEPMA0GA1UECwwGQ29uanVyMRowGAYDVQQDDBFJ +bnRlcm1lZGlhdGUgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AOoOC+ULIOJbIE9kn1785FbVwN3F+8PI7m+X8xkGwBqdhXh0ctdaC+5HpS/1cNTr +BmiXwAavyStcNmu7zgdmLOnwnlSyayn22b3G2sqLBuRIHQXJwa/yIBX4nrNkv40+ +JZrYfCTp9/cEiTkke3NPa44cgzqrFssRJSOBl4Hjd9CsPlsL5MT6vcvuSKdmcw38 +WVFOGEu+VRBwqhLpqmWpOH4bqGH8ddQy6WObjbNoRHMBD6fY3XTZBmmJCg/x7Fbb +mFmKK+oxsEzXOgs38bKU+KiannWFjbdIplytzCp1ynKEUUBNbUG7WSExyn3qpIzT +K6vXnRHenjX6sCxKDHxGSjaDNiMqNDi19xMGXRtVlmcWXAj9aKm64cA1+xZ7COMh +/iKIIqr2OdyaIRfx5eeVLZLdmCiL0FAHixE5bRAS/Ui/2XOvcfVZPAX4EswimS+t ++SfpPoKdpUIqXW+NxYdKFDbsE5076jup9kANwZyxhLBnb9mfDEfKHVNxZZ4Pa3N4 +4cfvZrbiayboCBKd2fJblnNQUnFb1q63asJX2zvKQTCmOdTaPKPGzlfoc8mw3792 +a9CncgY3WrVRVjMwtEM6/hcWzyCgE1YBhL+UF1DZmAj4RjuFgXz+/R8DRE0atRYz +brlIkngbjxDJdsfkkkH9VvvJeN6qalrvmMRDQNgMdOKJAgMBAAGjZjBkMB0GA1Ud +DgQWBBRf+xqIWDjEYwSL35LQh/Ttmb8yEjAfBgNVHSMEGDAWgBS2+AcI0/DyO2a9 +nuOFD6Teuo30CzASBgNVHRMBAf8ECDAGAQH/AgEUMA4GA1UdDwEB/wQEAwIBhjAN +BgkqhkiG9w0BAQsFAAOCAgEARNkLFYOGAnCft/opYtFalYa2K3bZlJIXRLUehpo/ +pyD1Su5gfAd5GSK91noG8XV7giuZyVYTZfUUjin2qjuBDL4pddpEOFtnQljOX783 +J6k0xAaGSbrxhahVTDhC7b8qbSrtncLB3g/6hOZP00t52RZ1OtjsiQt2ZL+3obuj +2/9fwzYRWYtc2QWx6LRyBhw/KX8tCERe6Eb1Hv8it4Lyt1wfIrq4KVuOjPlIQWXh +JLx52bZ+YKApExTbAKDvVKHzb5Yh6VzQimm+ju2XFzKYHrFkXDN6ACMJsNOvXr2p +Y03AXMkWJSSPlveWdP/Gy81qQ7CW62+p3cThf3VXRRIyjpadoE33Nzl+Mx/eGkfq +p0Ov/b/71YkRgZZp/UtgA1/uKrtQvv5iqBkItExMuCEN0GIhyxJ/iFpp85SlUHqF +5QbvxxIS8xjNdWwxwQoNHZe7fHoFcgNieaslrNdGiQqbTKZA5kF/LIS7ZbpwRvVK +UKUnEZP2oTiQ8YektUGGTFXO9M0kdM6WE79kND085GSO4nSPovbVqUWn776oLR3Q +9v36cFif2HT1yi+JmGc5PHKGTZD3d2CYhfP0DawtcUAca2zKOMjXT3NaXuxeQThi +QSuFXYVjXVwzDTOdQ6U8MpMftFzcVxbj0IXbJbutBBc5M3BXwc2vdicQ5FekRtfk +r6g= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwWzELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYD +VQQLDAZDb25qdXIxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTgxMTE5MTgzMDU5WhcN +MjgxMTE2MTgzMDU5WjB2MQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz +ZXR0czEPMA0GA1UEBwwGTmV3dG9uMREwDwYDVQQKDAhDeWJlckFyazEPMA0GA1UE +CwwGQ29uanVyMRowGAYDVQQDDBFJbnRlcm1lZGlhdGUgQ0EgMTCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMp6vnOADY8K1di8u9UMGOCGhbfIRXjEBi4M +S0o95z0raVLpJlmebdXBDGRqB0GhDE6nIdVvpQnJcb9XXupoIfjqHcvEL4mVZsbU +gzg45gNDBagcAHB1y5T2d0zuw9MJ9fDB7YK4oa8ByoAT1rXdf8+yuAaNXrvz6ENu +WdOx7pw3NY4qzah8Q8wBXB6toeX26wXkZ1WZHg30KMSwqcyJnUZrS53YVs3o5LqV +cGKPHTuCi4Orn/I/WgXA7qzaeRaQDQyf3NXGn8Ala7KZjQFAfAnjbiWrY3PbhKJf +TqhevFtI16+WMNXau1t70ouJcWjhgF4fZnwxCVhN3x/JWIIQL9vAvu1i9coAc460 +ZfNsESnYTY6T7KhQmGGpYslF8WhuPA1Rns7CXcdSHQulDdHJno3C+VO11wTHgSN4 +Erf5VjHZDmxU2wJZUU9sh+sZPPaReR2EFAPaPS3UDFXtvkf2I4iZiYXsdLR8QHi3 +WG7mtRzygP+Y8L5cfGLwMytrKxQjBQmuwlByA+L6UEr5qLWf7P/D/QuQyV3giqoE +UF7hGFXukA3+ePjdOhYczx+LIawsSRFSrcBBsxr2TAhJQtc5w6mSF17ceNMS2JUm +RICjVG2yJ+9Xb1XdwqwC4mqhyE13QNiu+/VbYW38iZXUJ+KRzqe1zRoQSO4+j2CZ +NYafddLXAgMBAAGjZjBkMB0GA1UdDgQWBBS2+AcI0/DyO2a9nuOFD6Teuo30CzAf +BgNVHSMEGDAWgBSTkIurMC/uaf/3O2yCnwFKEFYazzASBgNVHRMBAf8ECDAGAQH/ +AgEUMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAzfIGFqxezsUa +k77XK7a6uM4MIMo+dMhuVKf5bCuQTxFNsl7bCqe+mv94VtxG4T9k1b316iEctdeW +3I5WFaCkgQzZyYBVIQx0bONXYolAaEZDT42knHm8oYo5QkhvJHMsxk7Dg+uQ0QCm +7v0kFlZydnHSv66TBxCQYPa/Zw8LCboqY41zMyeUXgvsw+dA3W8cU1mpLLzyaIH4 +GziY/Xy+G+h/m/YcKMgb05FaaN6eR3ptQTzgJ5Zk5r1miFog6EzCGmdpybdp5mKq +L+hpem1piykGIalG35u8uYZg68Mouhv/HQZBG8iNpoE1jvGzXXNCGBOfJlUNcjOU +7wid08fxFEMsTMWLyBHnNAeAkB4K/Q3jeF8yym+DWVzlpA0ByP3vDSj3E6HYKy/I +jx/wQau+vFDDf97fTQ6iYX48/0E0Jkv7msgOdUASU5JZUQtMgQ9SwLP2jAdcWfZ+ +3c4FXJGAZlHjPedc/3AUYPGY4kb2Twndw1x2rw0iJ5v621KKxUiLFfn16JV2hJum +KJkhlfQhsyfHkvy/mz9ZYK/fI2KlVLcCFhYJiJbJtWPlKYk/AEeVXyAaMTB+Q0PD +v0E4ulNPMWw0oipIiQ6p8YxtAw5c1dwyD4la3A+7Yc0h5GDvNX6iuDBF8AdR5YqP +8a1pctJa7KVwWz3UDDiUIPuzwIYnKK4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIJAOW6Ge3ZCI+vMA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV +BAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMREwDwYDVQQKDAhDeWJlckFy +azEPMA0GA1UECwwGQ29uanVyMRAwDgYDVQQDDAdSb290IENBMB4XDTE4MTExOTE4 +MzA1MVoXDTM4MTExNDE4MzA1MVowWzELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDU1h +c3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYDVQQLDAZDb25qdXIx +EDAOBgNVBAMMB1Jvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDevPTMHUpuMDn2jRWI4JUtUBit8RWH1rROO6VODGmvk/KAm20hcJTMkoQS4Ev7 +kKU9AXt5e0lVm30S5XTHwn4DIWV3pu+tKFuLir9FrhvFyzykhc5a4kFOdnIRzt14 +HbXGdyLNT293wXL0JyNZQzGTqkoU+moDkDDnla/Br6JHtLAe87k2AF6zV1FD7hId +/fm2uPbhgGxJCpZNgfTT787kx8rPGzuVcVfEJBlu92N+WphJovAamzGoZN4IPv9s +yfR6hTy4iqpBcV/iK2/l+qwrhVwdYw341dUxt3zna3HSXh7dW/jOmJKeYawE0fML +stX3ayc481O9XmLOsivx2HfWrLD4OVBXyiAPp87Lb6sWcTOshTTAAbw/F+tFMkmb +hIeF+pCE6bAFe4RKdDtqlThtWuJD0O21w31hvDhGGi+hVlWI3cDnrJEf/flRLMwE +F0s7G6X+tox/QPe0rIa8Q+y+iJH8LrW2/4dItE4N+zUFuhuUojzS5PXkP4QoJ5wL +DndZ/cakvzS5qHzDyC6kBp+JVQDM2B7u47cPGR4zJ6ieHIxFKiJ2K+lqhqGUmI2n +ru0KwV9jTr9VXVo9Vt2wesaWnqX2P1Azp1vU5xRLHqm7MlZVzt/RefCVZXVhQ+fQ +C6B6zbcFElws1COIJ37YKLetYJe8iC2ZecYisJWjVl5yrwIDAQABo2MwYTAdBgNV +HQ4EFgQUk5CLqzAv7mn/9ztsgp8BShBWGs8wHwYDVR0jBBgwFoAUk5CLqzAv7mn/ +9ztsgp8BShBWGs8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQELBQADggIBAMk5ktQDSDZdS9hpNDpGVmFqWuJvybO+hLsnJHw5tKdY +5CvoV/K0eJI+E/puuIXthnUkPuR9NwIy4yZosqZpRydmAV/lqyIbVMyiT86f2t+B +LsGNbxFkyzG+n84ObWU8mAok20k4IUnNa5qtLj+rGAzK/aWb+oObjYlWNzESbtns +4rhHTTiRsGkWzD+3lnivJN2ftxi5Vx/95eC5HVURrBanIvilLTvZUzWus2F9cOei +VvsCpfiFdbQ7b2pFwMM3wKOf172knQSzTVbbsEJmx+O1WA2+K5FnzXkTYnp8Y+LS +9fT1QbntQyXMKdniyXatreGav5T462D8Q/D55r4a5MBzrlCbdyE8IZfuvOJDTW9h +yBg4gH378DEj/5khLrfai6X5uVH/qhJzHgwcGOOiHiE0ZbuPNiLiclp+BH2WMbit ++jqnGhd0hmFvIUVrtw3AV9SfPkN/sEREEgc2CWF0HVoBssqTLzMtSv13A1TGGml1 +5MdjCmXJ6OmIlOLJ2XfJWIEMa6Ax+V4lPHe9dNtZYuGZU4v6EaIB8YQTZMvt+9hn +SVKNivTRnQgJeHkXjH0rJugocn03CAioW0oVy4mCjjZ8L4apYOauzCvnRFb0NjmZ +0WHGLHCS/4/ZizWE9yU7TNnYR8JXnB1yK0oXOMJH6FARMVe2GGqQo4o8MtYiyXPu +-----END CERTIFICATE----- diff --git a/demos/ldap-integration/certs/ca.crt b/demos/ldap-integration/certs/ca.crt new file mode 100644 index 00000000..4c28c2d1 --- /dev/null +++ b/demos/ldap-integration/certs/ca.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIJAOW6Ge3ZCI+vMA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV +BAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMREwDwYDVQQKDAhDeWJlckFy +azEPMA0GA1UECwwGQ29uanVyMRAwDgYDVQQDDAdSb290IENBMB4XDTE4MTExOTE4 +MzA1MVoXDTM4MTExNDE4MzA1MVowWzELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDU1h +c3NhY2h1c2V0dHMxETAPBgNVBAoMCEN5YmVyQXJrMQ8wDQYDVQQLDAZDb25qdXIx +EDAOBgNVBAMMB1Jvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDevPTMHUpuMDn2jRWI4JUtUBit8RWH1rROO6VODGmvk/KAm20hcJTMkoQS4Ev7 +kKU9AXt5e0lVm30S5XTHwn4DIWV3pu+tKFuLir9FrhvFyzykhc5a4kFOdnIRzt14 +HbXGdyLNT293wXL0JyNZQzGTqkoU+moDkDDnla/Br6JHtLAe87k2AF6zV1FD7hId +/fm2uPbhgGxJCpZNgfTT787kx8rPGzuVcVfEJBlu92N+WphJovAamzGoZN4IPv9s +yfR6hTy4iqpBcV/iK2/l+qwrhVwdYw341dUxt3zna3HSXh7dW/jOmJKeYawE0fML +stX3ayc481O9XmLOsivx2HfWrLD4OVBXyiAPp87Lb6sWcTOshTTAAbw/F+tFMkmb +hIeF+pCE6bAFe4RKdDtqlThtWuJD0O21w31hvDhGGi+hVlWI3cDnrJEf/flRLMwE +F0s7G6X+tox/QPe0rIa8Q+y+iJH8LrW2/4dItE4N+zUFuhuUojzS5PXkP4QoJ5wL +DndZ/cakvzS5qHzDyC6kBp+JVQDM2B7u47cPGR4zJ6ieHIxFKiJ2K+lqhqGUmI2n +ru0KwV9jTr9VXVo9Vt2wesaWnqX2P1Azp1vU5xRLHqm7MlZVzt/RefCVZXVhQ+fQ +C6B6zbcFElws1COIJ37YKLetYJe8iC2ZecYisJWjVl5yrwIDAQABo2MwYTAdBgNV +HQ4EFgQUk5CLqzAv7mn/9ztsgp8BShBWGs8wHwYDVR0jBBgwFoAUk5CLqzAv7mn/ +9ztsgp8BShBWGs8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQELBQADggIBAMk5ktQDSDZdS9hpNDpGVmFqWuJvybO+hLsnJHw5tKdY +5CvoV/K0eJI+E/puuIXthnUkPuR9NwIy4yZosqZpRydmAV/lqyIbVMyiT86f2t+B +LsGNbxFkyzG+n84ObWU8mAok20k4IUnNa5qtLj+rGAzK/aWb+oObjYlWNzESbtns +4rhHTTiRsGkWzD+3lnivJN2ftxi5Vx/95eC5HVURrBanIvilLTvZUzWus2F9cOei +VvsCpfiFdbQ7b2pFwMM3wKOf172knQSzTVbbsEJmx+O1WA2+K5FnzXkTYnp8Y+LS +9fT1QbntQyXMKdniyXatreGav5T462D8Q/D55r4a5MBzrlCbdyE8IZfuvOJDTW9h +yBg4gH378DEj/5khLrfai6X5uVH/qhJzHgwcGOOiHiE0ZbuPNiLiclp+BH2WMbit ++jqnGhd0hmFvIUVrtw3AV9SfPkN/sEREEgc2CWF0HVoBssqTLzMtSv13A1TGGml1 +5MdjCmXJ6OmIlOLJ2XfJWIEMa6Ax+V4lPHe9dNtZYuGZU4v6EaIB8YQTZMvt+9hn +SVKNivTRnQgJeHkXjH0rJugocn03CAioW0oVy4mCjjZ8L4apYOauzCvnRFb0NjmZ +0WHGLHCS/4/ZizWE9yU7TNnYR8JXnB1yK0oXOMJH6FARMVe2GGqQo4o8MtYiyXPu +-----END CERTIFICATE----- diff --git a/demos/ldap-integration/certs/ldap.crt b/demos/ldap-integration/certs/ldap.crt new file mode 100644 index 00000000..081118a9 --- /dev/null +++ b/demos/ldap-integration/certs/ldap.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFqjCCA5KgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwdjELMAkGA1UEBhMCVVMx +FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcMBk5ld3RvbjERMA8GA1UE +CgwIQ3liZXJBcmsxDzANBgNVBAsMBkNvbmp1cjEaMBgGA1UEAwwRSW50ZXJtZWRp +YXRlIENBIDMwHhcNMTgxMTE5MTgzMTI3WhcNMTkxMTE5MTgzMTI3WjCBgDELMAkG +A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcMBk5ld3Rv +bjERMA8GA1UECgwIQ3liZXJBcmsxDzANBgNVBAsMBkNvbmp1cjEkMCIGA1UEAwwb +bGRhcC1zZXJ2ZXIubXljb21wYW55LmxvY2FsMIICIjANBgkqhkiG9w0BAQEFAAOC +Ag8AMIICCgKCAgEAog89aUSWM2CWZwilZ2We5GLjJdiM70lkwEhaPbyqK9pVTebd +iK1l0G8mQM0O90M2YezBnDQTZet8fr4HvuchgpNGRBu8VR6o2ZnEjvh2b7/0Dbfi +COCFZ6QlagtdRwM+xWuYdyp2VkHvvThYXEpI4+WwiVVVKthk106m9Frv13yb1uf5 +XOcNQc7WOPXNRSBHNv5G8mLHETrOVcmlzbE55RP97CE3IUIXGnyLI36wAtYJ0YkN +tfzHDo0eCBNrKKTghT6007bzphbdUaxzFyNXxG7u8QFb4NJ9G8xuGYn2RAnzh+fo +ZMAEcYvUcNdCPPMF1+3F9Acx4Bg1p0AJybTwH+i71BpQbS1e7+Rf7Vlnm+KMUlQI +nHcK4Ql1dCyaA72+le5Y3F0oFhONrAbqofKWrfG5bXKmUFSgpIQR0VucRTAKb/cZ +AoeIPuBKQD+115uV9NNhT5DQtq9lNzISFAKq2pfi1fCCaYW1urWjrbIaulEcbmpY +FQ0/FFnBN0xEndmBFGj/ZU3CoUzhbjZI9Eifga7X4XwSLEDGPnE9FHMOuEwBYy50 +ZjDIxLLI7a0vrd8khHCuIlfBRZFRIl2s+OJQMxnp3HyPb/WE6LPGAF4IibXtT9lc +aNnUfDyQtoDIA4Cx1MbVUacyJiTRIbU8MMUrRyx5GVi8wZP0JJRRMUht41kCAwEA +AaM3MDUwMwYDVR0RBCwwKoILbGRhcC1zZXJ2ZXKCG2xkYXAtc2VydmVyLm15Y29t +cGFueS5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAgEAAeV2AVz4g+c7CII3YCQTFeLx +AgY/ouPNjUCz5g40wc0Cc8db267zyoy1tqGLaldFUhE2J1thbvMWyh2JUBj2NsGt +B/kCKEX96pVO9DPrXqAi7r5G38yS7W05P4YGOV+O/kbd0T6bgs0yqYh1J52HS5dq +eufSCEco8S7eq6mWTn2YueXkc4edR35UqEyPmgurrJlKUJN/N1UZ8Mp8leDmy/El +FZAbn80+eSIIlsZJSkQpUGVEk5yvT8ggLECfmwIHzhZwrR2Gs2sQu9SYmNEqDdEP +W6NrCK2JYLaPBzJmOstgzaX/XUuB22Ua1gQ9j9QWOEfec9WXq8pGWuHb1rBQnBiK +MUwUq8yd572ezkzFuKpTGkMidr6JnPRbj4VeY0iFO6vaRN1fjXFekcDnOF5X11XV +P4kT+F4Hmn/WuMkXi/hlWKG1WR+VMxMtZOx3MNT8TzSXsRuvmqVCa5dwcrOtqKl8 +pMUSqxj/b2ruqCurUiErENmhGn5IMb6VDBkS59on0UoCYm6M7XmT2dpJNJn2LThk +DS/LDmqPBi0KmMwKAirtRZ7BJbPELMYorjsZvZlveBk9Lk+8oCH+W0QbGvvQp122 +CvxybQaSCDl+UtBbPXVdb6kkfHsx+fTTsmEP8ZYCVo0iZINWW8UzNI9WK+ZkwPOE +aKCk2BFdsOwpRC4RWl0= +-----END CERTIFICATE----- diff --git a/demos/ldap-integration/certs/ldap.key b/demos/ldap-integration/certs/ldap.key new file mode 100644 index 00000000..13f23e50 --- /dev/null +++ b/demos/ldap-integration/certs/ldap.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJJwIBAAKCAgEAog89aUSWM2CWZwilZ2We5GLjJdiM70lkwEhaPbyqK9pVTebd +iK1l0G8mQM0O90M2YezBnDQTZet8fr4HvuchgpNGRBu8VR6o2ZnEjvh2b7/0Dbfi +COCFZ6QlagtdRwM+xWuYdyp2VkHvvThYXEpI4+WwiVVVKthk106m9Frv13yb1uf5 +XOcNQc7WOPXNRSBHNv5G8mLHETrOVcmlzbE55RP97CE3IUIXGnyLI36wAtYJ0YkN +tfzHDo0eCBNrKKTghT6007bzphbdUaxzFyNXxG7u8QFb4NJ9G8xuGYn2RAnzh+fo +ZMAEcYvUcNdCPPMF1+3F9Acx4Bg1p0AJybTwH+i71BpQbS1e7+Rf7Vlnm+KMUlQI +nHcK4Ql1dCyaA72+le5Y3F0oFhONrAbqofKWrfG5bXKmUFSgpIQR0VucRTAKb/cZ +AoeIPuBKQD+115uV9NNhT5DQtq9lNzISFAKq2pfi1fCCaYW1urWjrbIaulEcbmpY +FQ0/FFnBN0xEndmBFGj/ZU3CoUzhbjZI9Eifga7X4XwSLEDGPnE9FHMOuEwBYy50 +ZjDIxLLI7a0vrd8khHCuIlfBRZFRIl2s+OJQMxnp3HyPb/WE6LPGAF4IibXtT9lc +aNnUfDyQtoDIA4Cx1MbVUacyJiTRIbU8MMUrRyx5GVi8wZP0JJRRMUht41kCAwEA +AQKCAgBTM73UwOjYgdtWFMNO3YaBPR/fu1lINQcsDTl/ftBjaVnogAH2/QdLxvT9 +ygnH+tL93Z7dQoM/DXLCY2/4nBPBRTmLGC5OCUqpRV/8AyZTY1q6fFDpO9RiDI1E +74a5QbpFg2Mosz1ENeAO5tG+uEjJ8I/9QjlSoPzM6c2foNyIZqpf4INPJjTRN48W +eWQk/FhzrILiSMJpXya2NqwQec/+g5AXXko+of7Yk16gH5fgLOGnmVTXvWq5Vsw3 +WzjmChhXcIVIOSLIf+6q0v3XwEZ8THQSeh8gwxCGaCOSqxkrf2xvtynCKC9f2Gl+ +cZXJUwAKB0JdciAyLFvHfYJI88Nf3TkfiuRMXcymfs0h9YbQp/hSSMJn67NsXJs8 +oBaiGpm7Wk+RGcUHEZZvRS4BIkQS+nOUGaPbJyRFrreawu6krxP0JXa2Dym5Bxcq +jMglnDRhLtL0JAjuSQ13kfN8UaifvTYKoClM6okkM18C6z4kQWoFP86EANcrFbJP +lt2cF7WJNS6IiGtB0yAnf0lBe+8nCWlC/nD5qj0uVJzX+X8OvgdRvTR7nB8Q4CQw +kPCZlriQlICHOA/nUHjy00wJQ6c4B+nHvvrzLlqwK65c1Rm0xmZjSxf5dQNsqM4w +gzqtpIXEg2a5iwP1N63N6JW2S1Oc9J/sdet3qkSCApKnNK3qHQKCAQEA1Gn7vy1s +lJJblGgH4r8bl5l3eKDn3MpdVVKUewm1nX6lbI0ArAwSV9Yk3BpFf/ClojKWRMXy +MYyscYh3ny6Kt6LGyezXButT8UdEY43m3hl738O5CBdq1Uzf/11Dpfb6VCzLvMQX +wRXF/vD+SaHrnCEiOdFET+bqU/MPts1U0yxS4kAVSz2MOT+LbRhtIl4ttb4YPB+q +q1lilOGNPWbtZ02TmsOUPpgyQ2nK+GKqCEbR6QjSIsweNPsCDqBWkKEmoPOMLfhd ++K+90gmnm3NS3m/eK/vdSTIhWm+boBhyopnL0K+lk0TRL3hDSFUtgFaUiLaC/xE1 +AKUTPPsMDZqhmwKCAQEAw1AoaVm2YEqYWVhAQdemJ2Eo3Yugj6qFmwQuAxX1550y +MKc+TzYLTnqtU4okCX3AcApyUBtjP/izrEUPu4zy19cECGjpVUMNqtyYNJsk1Q6g +gZRrj9hAoTGWkqm/zh0sX2RjP9Vw1Z0sWZuH1bh0oHefG3Xy8b3+4F5yIyP7LFCn +2aKfmBhXVdsoP03n3bRGqWKcVvKel8j2O6qshrcTdjCZGrci8Mbr9ilgdnLd2R3u +z41NpVz/fWKlulgY+XnSngBWKOCoU9AegAZIAq35EXzWdFuSnEalUnvZF5wDZTVb +htG0zI5yF/7jK4qeAiDwgmnTtpeUiSxTXcSmzlYIGwKCAQB4IsEZbU198hENrJDZ +M5EdetTRSuAYRfPnr97+f41SWDCjZlQ8+k7dkuYh/lHUfHyRcd7/Yp0KXS+ivrY5 +N4+JMO0Rg3xSE4LUcaRCUh2C/BLNidr6spPfs6z0twDtuvP166gHSTjOIcxr1k1b +w9KH6U18OdlS/50EgfIfR550GRt/jxL8DQFj14a52xjOWUmtAqieSKK0aseQwMir +M62NwZh77aXIiTfUXN9JADR+nd9W14BR4fQrrtOJBjIvdpVsbpKX5WLwpiTLyF4d +U2pJGCgl5DtRjKLEjV8NewZK5IUbsFwLIN7W5EPZgyNK9KzpbaBFNqwtgy+QS8ST +ZSOFAoIBAHwYahTF04LK4pGh6PHsur06lmRtWs7tYYZk2XdMdLl8v276VDSv+e8b +MxVpKAx/wc1uVcNgI2d59W73Uk+v9nv9Oaq+PcLWn9B36J1EFdrpOEIcs1rp4+aH +Q0xcXmnvT0os1oKwcsjG3G7yyxOX50ItvwILpxjBxzd3yr1ZFzXI6Vz2XsCcdqEu +ZhwSu8e5y0vEQ+FatjlqjkjK4GOX3t2xcxXuVlz1hucY0xlvUlWpFxr4hOUUeaCJ +FROY9gVMye1p+VRvqYPXMAnX89kAAMiDsR6tMDHrEQ+fcQf3MJEVndnDVETEHOny +IRSBNnPTyfySkNnq5Y1ihHWHhRSExRECggEAKnbGMwyVqBbgi2IV60bJ5ahyjc+m +SyauoMHaJjTVsRZqhUSq2xOQFCvoQCsmuUy1W5IppqZzXxhbh2e8pwL9gbFTQZvr +Y18eCLJ3yrOEBHNEPkVGBMzvH+Tr3bB8Da7SYJ4/CKC/pwNSPtdIDskgch9bySXh +cm+hNNjhKM1zuq6x/P1xnRqq4+SUMctUaysWYyfkwxxVigN5OEV3ce5dQsB6pDDN +Ffh453WhSpmPzb+wT3wNieW3xH2uIDPYTdX48NSfvTU6HdM+Kmu6trxYuezzOlPI +NtdyuYv5StPstfStRFJgUCf6BWH9brqoWDt4Vyiz/nypHtBAHttZN3+bOg== +-----END RSA PRIVATE KEY----- diff --git a/demos/ldap-integration/cli b/demos/ldap-integration/cli new file mode 100755 index 00000000..ffcbcb8b --- /dev/null +++ b/demos/ldap-integration/cli @@ -0,0 +1,29 @@ +#!/bin/bash -e + +function print_help() { + cat << EOF +NAME + cli - Development tool to simplify working with a Conjur container. CLI + proxies commands into the Conjur CLI container to simplify the process + of managing policy for development. + +SYNOPSIS + cli [global options] command [command options] [arguments...] +GLOBAL OPTIONS + --help - Show this message +EOF +exit +} + +function proxy_command { + cmd="$@" + docker-compose run --rm -w /src/cli --entrypoint /bin/bash client -c " + if [ ! -e /root/conjur-demo.pem ]; then + yes 'yes' | conjur init -u https://conjur-master.mycompany.local -a demo + fi + conjur authn login -u admin -p secret + eval exec \"$cmd\" + " +} + +proxy_command "$@" diff --git a/demos/ldap-integration/docker-compose.yml b/demos/ldap-integration/docker-compose.yml new file mode 100644 index 00000000..cac7a19e --- /dev/null +++ b/demos/ldap-integration/docker-compose.yml @@ -0,0 +1,59 @@ +version: "3" +services: + conjur-master.mycompany.local: + image: registry.tld/conjur-appliance:5.0-stable + ports: + - "443:443" + security_opt: + - "seccomp:unconfined" + volumes: + - backups:/opt/conjur/backup/ + - ./files:/conjur_files + links: + - ldap-server + + conjur-follower.mycompany.local: + image: registry.tld/conjur-appliance:5.0-stable + environment: + CONJUR_AUTHENTICATORS: "authn-ldap/ldap-server,authn" + CONJUR_AUTHN_URL: http://localhost/authn-ldap/ldap-server + ports: + - "444:443" + security_opt: + - "seccomp:unconfined" + volumes: + - backups:/opt/conjur/backup/ + - ./files:/conjur_files + links: + - ldap-server + + client: + image: cyberark/conjur-cli:5 + working_dir: -w /src/cli + environment: + CONJUR_APPLIANCE_URL: https://conjur-master.mycompany.local + CONJUR_ACCOUNT: demo + CONJUR_AUTHN_LOGIN: admin + volumes: + - .:/src/cli + - ./cli_cache:/root + + ldap-server: + image: osixia/openldap + hostname: ldap-server + command: --copy-service --loglevel debug + environment: + LDAP_ADMIN_PASSWORD: ldapsecret + LDAP_TLS: "true" + LDAP_TLS_CA_CRT_FILENAME: "ca-chain.crt" + LDAP_TLS_ENFORCE: "true" + LDAP_TLS_VERIFY_CLIENT: try + ports: + - "389:389" + - "636:636" + volumes: + - ./files/ldap:/opt/ldap + - ./certs:/container/service/slapd/assets/certs + +volumes: + backups: diff --git a/demos/ldap-integration/files/ldap/disable_anon_backend.ldif b/demos/ldap-integration/files/ldap/disable_anon_backend.ldif new file mode 100644 index 00000000..96dd7f1d --- /dev/null +++ b/demos/ldap-integration/files/ldap/disable_anon_backend.ldif @@ -0,0 +1,3 @@ +dn: olcDatabase={1}mdb,cn=config +add: olcRequires +olcRequires: authc diff --git a/demos/ldap-integration/files/ldap/disable_anon_frontend.ldif b/demos/ldap-integration/files/ldap/disable_anon_frontend.ldif new file mode 100644 index 00000000..af657172 --- /dev/null +++ b/demos/ldap-integration/files/ldap/disable_anon_frontend.ldif @@ -0,0 +1,3 @@ +dn: olcDatabase={-1}frontend,cn=config +add: olcRequires +olcRequires: authc diff --git a/demos/ldap-integration/files/ldap/test-ldap_groups.ldif b/demos/ldap-integration/files/ldap/test-ldap_groups.ldif new file mode 100644 index 00000000..78bcf51d --- /dev/null +++ b/demos/ldap-integration/files/ldap/test-ldap_groups.ldif @@ -0,0 +1,88 @@ +dn: cn=WinRMRemoteWMIUsers__,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: WinRMRemoteWMIUsers__ +gidNumber: 10001 + +dn: cn=Domain Computers,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Domain Computers +gidNumber: 10002 + +dn: cn=Domain Controllers,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Domain Controllers +gidNumber: 10003 + +dn: cn=Schema Admins,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Schema Admins +gidNumber: 10004 + +dn: cn=Enterprise Admins,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Enterprise Admins +gidNumber: 10005 +memberUid: Administrator + +dn: cn=Cert Publishers,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Cert Publishers +gidNumber: 10006 + +dn: cn=Domain Admins,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Domain Admins +gidNumber: 10007 +memberUid: Administrator + +dn: cn=Domain Users,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Domain Users +gidNumber: 10008 +memberUid: shani.gentry-cincott + +dn: cn=Domain Guests,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Domain Guests +gidNumber: 10009 + +dn: cn=Quality_Assurance,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: Quality_Assurance +gidNumber: 10010 + +dn: cn=_IT-OPS_,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: _IT-OPS_ +gidNumber: 10011 +memberUid: shani.gentry-cincott +memberUid: winupdate + +dn: cn=All Users,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: All Users +gidNumber: 10011 +memberUid: Guest +memberUid: Ekstrom +memberUid: Mike O'Brien +memberUid: shani.gentry-cincott +memberUid: testuser{42} +memberUid: ahole%20 +memberUid: nil +memberUid: winupdate +memberUid: Administrator +memberUid: krbtgt +memberUid: alice +memberUid: charles diff --git a/demos/ldap-integration/files/ldap/test-ldap_users.ldif b/demos/ldap-integration/files/ldap/test-ldap_users.ldif new file mode 100644 index 00000000..82feaca5 --- /dev/null +++ b/demos/ldap-integration/files/ldap/test-ldap_users.ldif @@ -0,0 +1,137 @@ +dn: cn=Guest,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah guest@example.org +cn: Guest +sn: Guest +description: Built-in account for guest access to the computer/domain +uid: Guest +uidNumber: 1 +gidNumber: 10009 +homeDirectory: /Users/Guest + +dn: cn=MathiÃ¥s Ekstrøm,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: MathiÃ¥s Ekstrøm +sn: Ekstrøm +description: QA Guy +uid: Ekstrom +uidNumber: 2 +gidNumber: 10010 +homeDirectory: /Users/Ekstr0m +memberOf: cn=Quality_Assurance,dc=example,dc=org + +dn: cn=Mike O'Brien,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: Mike O'Brien +sn: O'Brien +description: QA Guy +uid: Mike O'Brien +uidNumber: 3 +gidNumber: 10010 +homeDirectory: /Users/Mike O'Brien +memberOf: cn=Quality_Assurance,dc=example,dc=org + +dn: cn=Shani Gentry-Cincotti,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: Shani Gentry-Cincotti +sn: shani.gentry-cincott +uid: shani.gentry-cincott +uidNumber: 4 +gidNumber: 10011 +homeDirectory: /Users/shani.gentry-cincott + +dn: cn=test user,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: test user +sn: testuser{42} +uid: testuser{42} +uidNumber: 5 +gidNumber: 10007 +homeDirectory: /Users/testuser{42} + +dn: cn=URL A-HOLE,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: URL A-HOLE +sn: ahole%20 +uid: ahole%20 +uidNumber: 6 +gidNumber: 10007 +homeDirectory: /Users/ahole%20 + +dn: cn=nil,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: nil +sn: nil +uid: nil +uidNumber: 7 +gidnumber: 10008 +homeDirectory: /Users/nil + +dn: cn=winupdate,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: winupdate +sn: winupdate +uid: winupdate +uidNumber: 8 +gidNumber: 10011 +homeDirectory: /Users/winupdate + +dn: cn=Administrator,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: Administrator +sn: Administrator +description: Built-in account for administering the computer/domain +uid: Administrator +uidNumber: 9 +gidNumber: 10011 +homeDirectory: /Users/Administrator + +dn: cn=krbtgt,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +cn: krbtgt +sn: krbtgt +description: QA Guy +uid: krbtgt +uidNumber: 10 +gidNumber: 10010 +homeDirectory: /Users/krbtgt +memberOf: cn=Quality_Assurance,dc=example,dc=org + +dn: uid=alice,dc=example,dc=org +cn: Alice +sn: Smith +uid: alice +objectClass: person +objectClass: uidObject +objectClass: top +userPassword: alice + +dn: uid=charles,dc=example,dc=org +cn: Charles +sn: Berkeley +uid: charles +objectClass: person +objectClass: uidObject +objectClass: top +userPassword: charles diff --git a/demos/ldap-integration/files/ldap/test-perf_1000u_100g.ldif b/demos/ldap-integration/files/ldap/test-perf_1000u_100g.ldif new file mode 100644 index 00000000..cb60fec2 --- /dev/null +++ b/demos/ldap-integration/files/ldap/test-perf_1000u_100g.ldif @@ -0,0 +1,15600 @@ +dn: cn=user1,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user1@example.org +cn: user1 +sn: user1 +description: Generated user +uid: user1 +uidNumber: 10001 +gidNumber: 1 +homeDirectory: /home/user1 + +dn: cn=user2,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user2@example.org +cn: user2 +sn: user2 +description: Generated user +uid: user2 +uidNumber: 10002 +gidNumber: 1 +homeDirectory: /home/user2 + +dn: cn=user3,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user3@example.org +cn: user3 +sn: user3 +description: Generated user +uid: user3 +uidNumber: 10003 +gidNumber: 1 +homeDirectory: /home/user3 + +dn: cn=user4,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user4@example.org +cn: user4 +sn: user4 +description: Generated user +uid: user4 +uidNumber: 10004 +gidNumber: 1 +homeDirectory: /home/user4 + +dn: cn=user5,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user5@example.org +cn: user5 +sn: user5 +description: Generated user +uid: user5 +uidNumber: 10005 +gidNumber: 1 +homeDirectory: /home/user5 + +dn: cn=user6,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user6@example.org +cn: user6 +sn: user6 +description: Generated user +uid: user6 +uidNumber: 10006 +gidNumber: 1 +homeDirectory: /home/user6 + +dn: cn=user7,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user7@example.org +cn: user7 +sn: user7 +description: Generated user +uid: user7 +uidNumber: 10007 +gidNumber: 1 +homeDirectory: /home/user7 + +dn: cn=user8,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user8@example.org +cn: user8 +sn: user8 +description: Generated user +uid: user8 +uidNumber: 10008 +gidNumber: 1 +homeDirectory: /home/user8 + +dn: cn=user9,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user9@example.org +cn: user9 +sn: user9 +description: Generated user +uid: user9 +uidNumber: 10009 +gidNumber: 1 +homeDirectory: /home/user9 + +dn: cn=user10,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user10@example.org +cn: user10 +sn: user10 +description: Generated user +uid: user10 +uidNumber: 10010 +gidNumber: 1 +homeDirectory: /home/user10 + +dn: cn=user11,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user11@example.org +cn: user11 +sn: user11 +description: Generated user +uid: user11 +uidNumber: 10011 +gidNumber: 1 +homeDirectory: /home/user11 + +dn: cn=user12,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user12@example.org +cn: user12 +sn: user12 +description: Generated user +uid: user12 +uidNumber: 10012 +gidNumber: 1 +homeDirectory: /home/user12 + +dn: cn=user13,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user13@example.org +cn: user13 +sn: user13 +description: Generated user +uid: user13 +uidNumber: 10013 +gidNumber: 1 +homeDirectory: /home/user13 + +dn: cn=user14,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user14@example.org +cn: user14 +sn: user14 +description: Generated user +uid: user14 +uidNumber: 10014 +gidNumber: 1 +homeDirectory: /home/user14 + +dn: cn=user15,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user15@example.org +cn: user15 +sn: user15 +description: Generated user +uid: user15 +uidNumber: 10015 +gidNumber: 1 +homeDirectory: /home/user15 + +dn: cn=user16,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user16@example.org +cn: user16 +sn: user16 +description: Generated user +uid: user16 +uidNumber: 10016 +gidNumber: 1 +homeDirectory: /home/user16 + +dn: cn=user17,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user17@example.org +cn: user17 +sn: user17 +description: Generated user +uid: user17 +uidNumber: 10017 +gidNumber: 1 +homeDirectory: /home/user17 + +dn: cn=user18,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user18@example.org +cn: user18 +sn: user18 +description: Generated user +uid: user18 +uidNumber: 10018 +gidNumber: 1 +homeDirectory: /home/user18 + +dn: cn=user19,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user19@example.org +cn: user19 +sn: user19 +description: Generated user +uid: user19 +uidNumber: 10019 +gidNumber: 1 +homeDirectory: /home/user19 + +dn: cn=user20,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user20@example.org +cn: user20 +sn: user20 +description: Generated user +uid: user20 +uidNumber: 10020 +gidNumber: 1 +homeDirectory: /home/user20 + +dn: cn=user21,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user21@example.org +cn: user21 +sn: user21 +description: Generated user +uid: user21 +uidNumber: 10021 +gidNumber: 1 +homeDirectory: /home/user21 + +dn: cn=user22,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user22@example.org +cn: user22 +sn: user22 +description: Generated user +uid: user22 +uidNumber: 10022 +gidNumber: 1 +homeDirectory: /home/user22 + +dn: cn=user23,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user23@example.org +cn: user23 +sn: user23 +description: Generated user +uid: user23 +uidNumber: 10023 +gidNumber: 1 +homeDirectory: /home/user23 + +dn: cn=user24,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user24@example.org +cn: user24 +sn: user24 +description: Generated user +uid: user24 +uidNumber: 10024 +gidNumber: 1 +homeDirectory: /home/user24 + +dn: cn=user25,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user25@example.org +cn: user25 +sn: user25 +description: Generated user +uid: user25 +uidNumber: 10025 +gidNumber: 1 +homeDirectory: /home/user25 + +dn: cn=user26,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user26@example.org +cn: user26 +sn: user26 +description: Generated user +uid: user26 +uidNumber: 10026 +gidNumber: 1 +homeDirectory: /home/user26 + +dn: cn=user27,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user27@example.org +cn: user27 +sn: user27 +description: Generated user +uid: user27 +uidNumber: 10027 +gidNumber: 1 +homeDirectory: /home/user27 + +dn: cn=user28,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user28@example.org +cn: user28 +sn: user28 +description: Generated user +uid: user28 +uidNumber: 10028 +gidNumber: 1 +homeDirectory: /home/user28 + +dn: cn=user29,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user29@example.org +cn: user29 +sn: user29 +description: Generated user +uid: user29 +uidNumber: 10029 +gidNumber: 1 +homeDirectory: /home/user29 + +dn: cn=user30,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user30@example.org +cn: user30 +sn: user30 +description: Generated user +uid: user30 +uidNumber: 10030 +gidNumber: 1 +homeDirectory: /home/user30 + +dn: cn=user31,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user31@example.org +cn: user31 +sn: user31 +description: Generated user +uid: user31 +uidNumber: 10031 +gidNumber: 1 +homeDirectory: /home/user31 + +dn: cn=user32,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user32@example.org +cn: user32 +sn: user32 +description: Generated user +uid: user32 +uidNumber: 10032 +gidNumber: 1 +homeDirectory: /home/user32 + +dn: cn=user33,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user33@example.org +cn: user33 +sn: user33 +description: Generated user +uid: user33 +uidNumber: 10033 +gidNumber: 1 +homeDirectory: /home/user33 + +dn: cn=user34,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user34@example.org +cn: user34 +sn: user34 +description: Generated user +uid: user34 +uidNumber: 10034 +gidNumber: 1 +homeDirectory: /home/user34 + +dn: cn=user35,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user35@example.org +cn: user35 +sn: user35 +description: Generated user +uid: user35 +uidNumber: 10035 +gidNumber: 1 +homeDirectory: /home/user35 + +dn: cn=user36,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user36@example.org +cn: user36 +sn: user36 +description: Generated user +uid: user36 +uidNumber: 10036 +gidNumber: 1 +homeDirectory: /home/user36 + +dn: cn=user37,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user37@example.org +cn: user37 +sn: user37 +description: Generated user +uid: user37 +uidNumber: 10037 +gidNumber: 1 +homeDirectory: /home/user37 + +dn: cn=user38,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user38@example.org +cn: user38 +sn: user38 +description: Generated user +uid: user38 +uidNumber: 10038 +gidNumber: 1 +homeDirectory: /home/user38 + +dn: cn=user39,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user39@example.org +cn: user39 +sn: user39 +description: Generated user +uid: user39 +uidNumber: 10039 +gidNumber: 1 +homeDirectory: /home/user39 + +dn: cn=user40,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user40@example.org +cn: user40 +sn: user40 +description: Generated user +uid: user40 +uidNumber: 10040 +gidNumber: 1 +homeDirectory: /home/user40 + +dn: cn=user41,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user41@example.org +cn: user41 +sn: user41 +description: Generated user +uid: user41 +uidNumber: 10041 +gidNumber: 1 +homeDirectory: /home/user41 + +dn: cn=user42,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user42@example.org +cn: user42 +sn: user42 +description: Generated user +uid: user42 +uidNumber: 10042 +gidNumber: 1 +homeDirectory: /home/user42 + +dn: cn=user43,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user43@example.org +cn: user43 +sn: user43 +description: Generated user +uid: user43 +uidNumber: 10043 +gidNumber: 1 +homeDirectory: /home/user43 + +dn: cn=user44,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user44@example.org +cn: user44 +sn: user44 +description: Generated user +uid: user44 +uidNumber: 10044 +gidNumber: 1 +homeDirectory: /home/user44 + +dn: cn=user45,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user45@example.org +cn: user45 +sn: user45 +description: Generated user +uid: user45 +uidNumber: 10045 +gidNumber: 1 +homeDirectory: /home/user45 + +dn: cn=user46,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user46@example.org +cn: user46 +sn: user46 +description: Generated user +uid: user46 +uidNumber: 10046 +gidNumber: 1 +homeDirectory: /home/user46 + +dn: cn=user47,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user47@example.org +cn: user47 +sn: user47 +description: Generated user +uid: user47 +uidNumber: 10047 +gidNumber: 1 +homeDirectory: /home/user47 + +dn: cn=user48,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user48@example.org +cn: user48 +sn: user48 +description: Generated user +uid: user48 +uidNumber: 10048 +gidNumber: 1 +homeDirectory: /home/user48 + +dn: cn=user49,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user49@example.org +cn: user49 +sn: user49 +description: Generated user +uid: user49 +uidNumber: 10049 +gidNumber: 1 +homeDirectory: /home/user49 + +dn: cn=user50,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user50@example.org +cn: user50 +sn: user50 +description: Generated user +uid: user50 +uidNumber: 10050 +gidNumber: 1 +homeDirectory: /home/user50 + +dn: cn=user51,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user51@example.org +cn: user51 +sn: user51 +description: Generated user +uid: user51 +uidNumber: 10051 +gidNumber: 1 +homeDirectory: /home/user51 + +dn: cn=user52,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user52@example.org +cn: user52 +sn: user52 +description: Generated user +uid: user52 +uidNumber: 10052 +gidNumber: 1 +homeDirectory: /home/user52 + +dn: cn=user53,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user53@example.org +cn: user53 +sn: user53 +description: Generated user +uid: user53 +uidNumber: 10053 +gidNumber: 1 +homeDirectory: /home/user53 + +dn: cn=user54,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user54@example.org +cn: user54 +sn: user54 +description: Generated user +uid: user54 +uidNumber: 10054 +gidNumber: 1 +homeDirectory: /home/user54 + +dn: cn=user55,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user55@example.org +cn: user55 +sn: user55 +description: Generated user +uid: user55 +uidNumber: 10055 +gidNumber: 1 +homeDirectory: /home/user55 + +dn: cn=user56,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user56@example.org +cn: user56 +sn: user56 +description: Generated user +uid: user56 +uidNumber: 10056 +gidNumber: 1 +homeDirectory: /home/user56 + +dn: cn=user57,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user57@example.org +cn: user57 +sn: user57 +description: Generated user +uid: user57 +uidNumber: 10057 +gidNumber: 1 +homeDirectory: /home/user57 + +dn: cn=user58,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user58@example.org +cn: user58 +sn: user58 +description: Generated user +uid: user58 +uidNumber: 10058 +gidNumber: 1 +homeDirectory: /home/user58 + +dn: cn=user59,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user59@example.org +cn: user59 +sn: user59 +description: Generated user +uid: user59 +uidNumber: 10059 +gidNumber: 1 +homeDirectory: /home/user59 + +dn: cn=user60,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user60@example.org +cn: user60 +sn: user60 +description: Generated user +uid: user60 +uidNumber: 10060 +gidNumber: 1 +homeDirectory: /home/user60 + +dn: cn=user61,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user61@example.org +cn: user61 +sn: user61 +description: Generated user +uid: user61 +uidNumber: 10061 +gidNumber: 1 +homeDirectory: /home/user61 + +dn: cn=user62,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user62@example.org +cn: user62 +sn: user62 +description: Generated user +uid: user62 +uidNumber: 10062 +gidNumber: 1 +homeDirectory: /home/user62 + +dn: cn=user63,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user63@example.org +cn: user63 +sn: user63 +description: Generated user +uid: user63 +uidNumber: 10063 +gidNumber: 1 +homeDirectory: /home/user63 + +dn: cn=user64,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user64@example.org +cn: user64 +sn: user64 +description: Generated user +uid: user64 +uidNumber: 10064 +gidNumber: 1 +homeDirectory: /home/user64 + +dn: cn=user65,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user65@example.org +cn: user65 +sn: user65 +description: Generated user +uid: user65 +uidNumber: 10065 +gidNumber: 1 +homeDirectory: /home/user65 + +dn: cn=user66,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user66@example.org +cn: user66 +sn: user66 +description: Generated user +uid: user66 +uidNumber: 10066 +gidNumber: 1 +homeDirectory: /home/user66 + +dn: cn=user67,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user67@example.org +cn: user67 +sn: user67 +description: Generated user +uid: user67 +uidNumber: 10067 +gidNumber: 1 +homeDirectory: /home/user67 + +dn: cn=user68,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user68@example.org +cn: user68 +sn: user68 +description: Generated user +uid: user68 +uidNumber: 10068 +gidNumber: 1 +homeDirectory: /home/user68 + +dn: cn=user69,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user69@example.org +cn: user69 +sn: user69 +description: Generated user +uid: user69 +uidNumber: 10069 +gidNumber: 1 +homeDirectory: /home/user69 + +dn: cn=user70,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user70@example.org +cn: user70 +sn: user70 +description: Generated user +uid: user70 +uidNumber: 10070 +gidNumber: 1 +homeDirectory: /home/user70 + +dn: cn=user71,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user71@example.org +cn: user71 +sn: user71 +description: Generated user +uid: user71 +uidNumber: 10071 +gidNumber: 1 +homeDirectory: /home/user71 + +dn: cn=user72,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user72@example.org +cn: user72 +sn: user72 +description: Generated user +uid: user72 +uidNumber: 10072 +gidNumber: 1 +homeDirectory: /home/user72 + +dn: cn=user73,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user73@example.org +cn: user73 +sn: user73 +description: Generated user +uid: user73 +uidNumber: 10073 +gidNumber: 1 +homeDirectory: /home/user73 + +dn: cn=user74,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user74@example.org +cn: user74 +sn: user74 +description: Generated user +uid: user74 +uidNumber: 10074 +gidNumber: 1 +homeDirectory: /home/user74 + +dn: cn=user75,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user75@example.org +cn: user75 +sn: user75 +description: Generated user +uid: user75 +uidNumber: 10075 +gidNumber: 1 +homeDirectory: /home/user75 + +dn: cn=user76,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user76@example.org +cn: user76 +sn: user76 +description: Generated user +uid: user76 +uidNumber: 10076 +gidNumber: 1 +homeDirectory: /home/user76 + +dn: cn=user77,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user77@example.org +cn: user77 +sn: user77 +description: Generated user +uid: user77 +uidNumber: 10077 +gidNumber: 1 +homeDirectory: /home/user77 + +dn: cn=user78,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user78@example.org +cn: user78 +sn: user78 +description: Generated user +uid: user78 +uidNumber: 10078 +gidNumber: 1 +homeDirectory: /home/user78 + +dn: cn=user79,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user79@example.org +cn: user79 +sn: user79 +description: Generated user +uid: user79 +uidNumber: 10079 +gidNumber: 1 +homeDirectory: /home/user79 + +dn: cn=user80,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user80@example.org +cn: user80 +sn: user80 +description: Generated user +uid: user80 +uidNumber: 10080 +gidNumber: 1 +homeDirectory: /home/user80 + +dn: cn=user81,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user81@example.org +cn: user81 +sn: user81 +description: Generated user +uid: user81 +uidNumber: 10081 +gidNumber: 1 +homeDirectory: /home/user81 + +dn: cn=user82,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user82@example.org +cn: user82 +sn: user82 +description: Generated user +uid: user82 +uidNumber: 10082 +gidNumber: 1 +homeDirectory: /home/user82 + +dn: cn=user83,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user83@example.org +cn: user83 +sn: user83 +description: Generated user +uid: user83 +uidNumber: 10083 +gidNumber: 1 +homeDirectory: /home/user83 + +dn: cn=user84,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user84@example.org +cn: user84 +sn: user84 +description: Generated user +uid: user84 +uidNumber: 10084 +gidNumber: 1 +homeDirectory: /home/user84 + +dn: cn=user85,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user85@example.org +cn: user85 +sn: user85 +description: Generated user +uid: user85 +uidNumber: 10085 +gidNumber: 1 +homeDirectory: /home/user85 + +dn: cn=user86,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user86@example.org +cn: user86 +sn: user86 +description: Generated user +uid: user86 +uidNumber: 10086 +gidNumber: 1 +homeDirectory: /home/user86 + +dn: cn=user87,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user87@example.org +cn: user87 +sn: user87 +description: Generated user +uid: user87 +uidNumber: 10087 +gidNumber: 1 +homeDirectory: /home/user87 + +dn: cn=user88,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user88@example.org +cn: user88 +sn: user88 +description: Generated user +uid: user88 +uidNumber: 10088 +gidNumber: 1 +homeDirectory: /home/user88 + +dn: cn=user89,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user89@example.org +cn: user89 +sn: user89 +description: Generated user +uid: user89 +uidNumber: 10089 +gidNumber: 1 +homeDirectory: /home/user89 + +dn: cn=user90,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user90@example.org +cn: user90 +sn: user90 +description: Generated user +uid: user90 +uidNumber: 10090 +gidNumber: 1 +homeDirectory: /home/user90 + +dn: cn=user91,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user91@example.org +cn: user91 +sn: user91 +description: Generated user +uid: user91 +uidNumber: 10091 +gidNumber: 1 +homeDirectory: /home/user91 + +dn: cn=user92,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user92@example.org +cn: user92 +sn: user92 +description: Generated user +uid: user92 +uidNumber: 10092 +gidNumber: 1 +homeDirectory: /home/user92 + +dn: cn=user93,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user93@example.org +cn: user93 +sn: user93 +description: Generated user +uid: user93 +uidNumber: 10093 +gidNumber: 1 +homeDirectory: /home/user93 + +dn: cn=user94,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user94@example.org +cn: user94 +sn: user94 +description: Generated user +uid: user94 +uidNumber: 10094 +gidNumber: 1 +homeDirectory: /home/user94 + +dn: cn=user95,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user95@example.org +cn: user95 +sn: user95 +description: Generated user +uid: user95 +uidNumber: 10095 +gidNumber: 1 +homeDirectory: /home/user95 + +dn: cn=user96,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user96@example.org +cn: user96 +sn: user96 +description: Generated user +uid: user96 +uidNumber: 10096 +gidNumber: 1 +homeDirectory: /home/user96 + +dn: cn=user97,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user97@example.org +cn: user97 +sn: user97 +description: Generated user +uid: user97 +uidNumber: 10097 +gidNumber: 1 +homeDirectory: /home/user97 + +dn: cn=user98,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user98@example.org +cn: user98 +sn: user98 +description: Generated user +uid: user98 +uidNumber: 10098 +gidNumber: 1 +homeDirectory: /home/user98 + +dn: cn=user99,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user99@example.org +cn: user99 +sn: user99 +description: Generated user +uid: user99 +uidNumber: 10099 +gidNumber: 1 +homeDirectory: /home/user99 + +dn: cn=user100,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user100@example.org +cn: user100 +sn: user100 +description: Generated user +uid: user100 +uidNumber: 10100 +gidNumber: 1 +homeDirectory: /home/user100 + +dn: cn=user101,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user101@example.org +cn: user101 +sn: user101 +description: Generated user +uid: user101 +uidNumber: 10101 +gidNumber: 1 +homeDirectory: /home/user101 + +dn: cn=user102,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user102@example.org +cn: user102 +sn: user102 +description: Generated user +uid: user102 +uidNumber: 10102 +gidNumber: 1 +homeDirectory: /home/user102 + +dn: cn=user103,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user103@example.org +cn: user103 +sn: user103 +description: Generated user +uid: user103 +uidNumber: 10103 +gidNumber: 1 +homeDirectory: /home/user103 + +dn: cn=user104,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user104@example.org +cn: user104 +sn: user104 +description: Generated user +uid: user104 +uidNumber: 10104 +gidNumber: 1 +homeDirectory: /home/user104 + +dn: cn=user105,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user105@example.org +cn: user105 +sn: user105 +description: Generated user +uid: user105 +uidNumber: 10105 +gidNumber: 1 +homeDirectory: /home/user105 + +dn: cn=user106,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user106@example.org +cn: user106 +sn: user106 +description: Generated user +uid: user106 +uidNumber: 10106 +gidNumber: 1 +homeDirectory: /home/user106 + +dn: cn=user107,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user107@example.org +cn: user107 +sn: user107 +description: Generated user +uid: user107 +uidNumber: 10107 +gidNumber: 1 +homeDirectory: /home/user107 + +dn: cn=user108,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user108@example.org +cn: user108 +sn: user108 +description: Generated user +uid: user108 +uidNumber: 10108 +gidNumber: 1 +homeDirectory: /home/user108 + +dn: cn=user109,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user109@example.org +cn: user109 +sn: user109 +description: Generated user +uid: user109 +uidNumber: 10109 +gidNumber: 1 +homeDirectory: /home/user109 + +dn: cn=user110,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user110@example.org +cn: user110 +sn: user110 +description: Generated user +uid: user110 +uidNumber: 10110 +gidNumber: 1 +homeDirectory: /home/user110 + +dn: cn=user111,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user111@example.org +cn: user111 +sn: user111 +description: Generated user +uid: user111 +uidNumber: 10111 +gidNumber: 1 +homeDirectory: /home/user111 + +dn: cn=user112,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user112@example.org +cn: user112 +sn: user112 +description: Generated user +uid: user112 +uidNumber: 10112 +gidNumber: 1 +homeDirectory: /home/user112 + +dn: cn=user113,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user113@example.org +cn: user113 +sn: user113 +description: Generated user +uid: user113 +uidNumber: 10113 +gidNumber: 1 +homeDirectory: /home/user113 + +dn: cn=user114,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user114@example.org +cn: user114 +sn: user114 +description: Generated user +uid: user114 +uidNumber: 10114 +gidNumber: 1 +homeDirectory: /home/user114 + +dn: cn=user115,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user115@example.org +cn: user115 +sn: user115 +description: Generated user +uid: user115 +uidNumber: 10115 +gidNumber: 1 +homeDirectory: /home/user115 + +dn: cn=user116,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user116@example.org +cn: user116 +sn: user116 +description: Generated user +uid: user116 +uidNumber: 10116 +gidNumber: 1 +homeDirectory: /home/user116 + +dn: cn=user117,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user117@example.org +cn: user117 +sn: user117 +description: Generated user +uid: user117 +uidNumber: 10117 +gidNumber: 1 +homeDirectory: /home/user117 + +dn: cn=user118,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user118@example.org +cn: user118 +sn: user118 +description: Generated user +uid: user118 +uidNumber: 10118 +gidNumber: 1 +homeDirectory: /home/user118 + +dn: cn=user119,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user119@example.org +cn: user119 +sn: user119 +description: Generated user +uid: user119 +uidNumber: 10119 +gidNumber: 1 +homeDirectory: /home/user119 + +dn: cn=user120,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user120@example.org +cn: user120 +sn: user120 +description: Generated user +uid: user120 +uidNumber: 10120 +gidNumber: 1 +homeDirectory: /home/user120 + +dn: cn=user121,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user121@example.org +cn: user121 +sn: user121 +description: Generated user +uid: user121 +uidNumber: 10121 +gidNumber: 1 +homeDirectory: /home/user121 + +dn: cn=user122,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user122@example.org +cn: user122 +sn: user122 +description: Generated user +uid: user122 +uidNumber: 10122 +gidNumber: 1 +homeDirectory: /home/user122 + +dn: cn=user123,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user123@example.org +cn: user123 +sn: user123 +description: Generated user +uid: user123 +uidNumber: 10123 +gidNumber: 1 +homeDirectory: /home/user123 + +dn: cn=user124,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user124@example.org +cn: user124 +sn: user124 +description: Generated user +uid: user124 +uidNumber: 10124 +gidNumber: 1 +homeDirectory: /home/user124 + +dn: cn=user125,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user125@example.org +cn: user125 +sn: user125 +description: Generated user +uid: user125 +uidNumber: 10125 +gidNumber: 1 +homeDirectory: /home/user125 + +dn: cn=user126,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user126@example.org +cn: user126 +sn: user126 +description: Generated user +uid: user126 +uidNumber: 10126 +gidNumber: 1 +homeDirectory: /home/user126 + +dn: cn=user127,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user127@example.org +cn: user127 +sn: user127 +description: Generated user +uid: user127 +uidNumber: 10127 +gidNumber: 1 +homeDirectory: /home/user127 + +dn: cn=user128,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user128@example.org +cn: user128 +sn: user128 +description: Generated user +uid: user128 +uidNumber: 10128 +gidNumber: 1 +homeDirectory: /home/user128 + +dn: cn=user129,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user129@example.org +cn: user129 +sn: user129 +description: Generated user +uid: user129 +uidNumber: 10129 +gidNumber: 1 +homeDirectory: /home/user129 + +dn: cn=user130,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user130@example.org +cn: user130 +sn: user130 +description: Generated user +uid: user130 +uidNumber: 10130 +gidNumber: 1 +homeDirectory: /home/user130 + +dn: cn=user131,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user131@example.org +cn: user131 +sn: user131 +description: Generated user +uid: user131 +uidNumber: 10131 +gidNumber: 1 +homeDirectory: /home/user131 + +dn: cn=user132,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user132@example.org +cn: user132 +sn: user132 +description: Generated user +uid: user132 +uidNumber: 10132 +gidNumber: 1 +homeDirectory: /home/user132 + +dn: cn=user133,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user133@example.org +cn: user133 +sn: user133 +description: Generated user +uid: user133 +uidNumber: 10133 +gidNumber: 1 +homeDirectory: /home/user133 + +dn: cn=user134,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user134@example.org +cn: user134 +sn: user134 +description: Generated user +uid: user134 +uidNumber: 10134 +gidNumber: 1 +homeDirectory: /home/user134 + +dn: cn=user135,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user135@example.org +cn: user135 +sn: user135 +description: Generated user +uid: user135 +uidNumber: 10135 +gidNumber: 1 +homeDirectory: /home/user135 + +dn: cn=user136,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user136@example.org +cn: user136 +sn: user136 +description: Generated user +uid: user136 +uidNumber: 10136 +gidNumber: 1 +homeDirectory: /home/user136 + +dn: cn=user137,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user137@example.org +cn: user137 +sn: user137 +description: Generated user +uid: user137 +uidNumber: 10137 +gidNumber: 1 +homeDirectory: /home/user137 + +dn: cn=user138,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user138@example.org +cn: user138 +sn: user138 +description: Generated user +uid: user138 +uidNumber: 10138 +gidNumber: 1 +homeDirectory: /home/user138 + +dn: cn=user139,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user139@example.org +cn: user139 +sn: user139 +description: Generated user +uid: user139 +uidNumber: 10139 +gidNumber: 1 +homeDirectory: /home/user139 + +dn: cn=user140,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user140@example.org +cn: user140 +sn: user140 +description: Generated user +uid: user140 +uidNumber: 10140 +gidNumber: 1 +homeDirectory: /home/user140 + +dn: cn=user141,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user141@example.org +cn: user141 +sn: user141 +description: Generated user +uid: user141 +uidNumber: 10141 +gidNumber: 1 +homeDirectory: /home/user141 + +dn: cn=user142,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user142@example.org +cn: user142 +sn: user142 +description: Generated user +uid: user142 +uidNumber: 10142 +gidNumber: 1 +homeDirectory: /home/user142 + +dn: cn=user143,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user143@example.org +cn: user143 +sn: user143 +description: Generated user +uid: user143 +uidNumber: 10143 +gidNumber: 1 +homeDirectory: /home/user143 + +dn: cn=user144,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user144@example.org +cn: user144 +sn: user144 +description: Generated user +uid: user144 +uidNumber: 10144 +gidNumber: 1 +homeDirectory: /home/user144 + +dn: cn=user145,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user145@example.org +cn: user145 +sn: user145 +description: Generated user +uid: user145 +uidNumber: 10145 +gidNumber: 1 +homeDirectory: /home/user145 + +dn: cn=user146,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user146@example.org +cn: user146 +sn: user146 +description: Generated user +uid: user146 +uidNumber: 10146 +gidNumber: 1 +homeDirectory: /home/user146 + +dn: cn=user147,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user147@example.org +cn: user147 +sn: user147 +description: Generated user +uid: user147 +uidNumber: 10147 +gidNumber: 1 +homeDirectory: /home/user147 + +dn: cn=user148,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user148@example.org +cn: user148 +sn: user148 +description: Generated user +uid: user148 +uidNumber: 10148 +gidNumber: 1 +homeDirectory: /home/user148 + +dn: cn=user149,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user149@example.org +cn: user149 +sn: user149 +description: Generated user +uid: user149 +uidNumber: 10149 +gidNumber: 1 +homeDirectory: /home/user149 + +dn: cn=user150,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user150@example.org +cn: user150 +sn: user150 +description: Generated user +uid: user150 +uidNumber: 10150 +gidNumber: 1 +homeDirectory: /home/user150 + +dn: cn=user151,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user151@example.org +cn: user151 +sn: user151 +description: Generated user +uid: user151 +uidNumber: 10151 +gidNumber: 1 +homeDirectory: /home/user151 + +dn: cn=user152,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user152@example.org +cn: user152 +sn: user152 +description: Generated user +uid: user152 +uidNumber: 10152 +gidNumber: 1 +homeDirectory: /home/user152 + +dn: cn=user153,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user153@example.org +cn: user153 +sn: user153 +description: Generated user +uid: user153 +uidNumber: 10153 +gidNumber: 1 +homeDirectory: /home/user153 + +dn: cn=user154,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user154@example.org +cn: user154 +sn: user154 +description: Generated user +uid: user154 +uidNumber: 10154 +gidNumber: 1 +homeDirectory: /home/user154 + +dn: cn=user155,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user155@example.org +cn: user155 +sn: user155 +description: Generated user +uid: user155 +uidNumber: 10155 +gidNumber: 1 +homeDirectory: /home/user155 + +dn: cn=user156,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user156@example.org +cn: user156 +sn: user156 +description: Generated user +uid: user156 +uidNumber: 10156 +gidNumber: 1 +homeDirectory: /home/user156 + +dn: cn=user157,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user157@example.org +cn: user157 +sn: user157 +description: Generated user +uid: user157 +uidNumber: 10157 +gidNumber: 1 +homeDirectory: /home/user157 + +dn: cn=user158,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user158@example.org +cn: user158 +sn: user158 +description: Generated user +uid: user158 +uidNumber: 10158 +gidNumber: 1 +homeDirectory: /home/user158 + +dn: cn=user159,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user159@example.org +cn: user159 +sn: user159 +description: Generated user +uid: user159 +uidNumber: 10159 +gidNumber: 1 +homeDirectory: /home/user159 + +dn: cn=user160,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user160@example.org +cn: user160 +sn: user160 +description: Generated user +uid: user160 +uidNumber: 10160 +gidNumber: 1 +homeDirectory: /home/user160 + +dn: cn=user161,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user161@example.org +cn: user161 +sn: user161 +description: Generated user +uid: user161 +uidNumber: 10161 +gidNumber: 1 +homeDirectory: /home/user161 + +dn: cn=user162,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user162@example.org +cn: user162 +sn: user162 +description: Generated user +uid: user162 +uidNumber: 10162 +gidNumber: 1 +homeDirectory: /home/user162 + +dn: cn=user163,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user163@example.org +cn: user163 +sn: user163 +description: Generated user +uid: user163 +uidNumber: 10163 +gidNumber: 1 +homeDirectory: /home/user163 + +dn: cn=user164,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user164@example.org +cn: user164 +sn: user164 +description: Generated user +uid: user164 +uidNumber: 10164 +gidNumber: 1 +homeDirectory: /home/user164 + +dn: cn=user165,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user165@example.org +cn: user165 +sn: user165 +description: Generated user +uid: user165 +uidNumber: 10165 +gidNumber: 1 +homeDirectory: /home/user165 + +dn: cn=user166,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user166@example.org +cn: user166 +sn: user166 +description: Generated user +uid: user166 +uidNumber: 10166 +gidNumber: 1 +homeDirectory: /home/user166 + +dn: cn=user167,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user167@example.org +cn: user167 +sn: user167 +description: Generated user +uid: user167 +uidNumber: 10167 +gidNumber: 1 +homeDirectory: /home/user167 + +dn: cn=user168,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user168@example.org +cn: user168 +sn: user168 +description: Generated user +uid: user168 +uidNumber: 10168 +gidNumber: 1 +homeDirectory: /home/user168 + +dn: cn=user169,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user169@example.org +cn: user169 +sn: user169 +description: Generated user +uid: user169 +uidNumber: 10169 +gidNumber: 1 +homeDirectory: /home/user169 + +dn: cn=user170,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user170@example.org +cn: user170 +sn: user170 +description: Generated user +uid: user170 +uidNumber: 10170 +gidNumber: 1 +homeDirectory: /home/user170 + +dn: cn=user171,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user171@example.org +cn: user171 +sn: user171 +description: Generated user +uid: user171 +uidNumber: 10171 +gidNumber: 1 +homeDirectory: /home/user171 + +dn: cn=user172,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user172@example.org +cn: user172 +sn: user172 +description: Generated user +uid: user172 +uidNumber: 10172 +gidNumber: 1 +homeDirectory: /home/user172 + +dn: cn=user173,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user173@example.org +cn: user173 +sn: user173 +description: Generated user +uid: user173 +uidNumber: 10173 +gidNumber: 1 +homeDirectory: /home/user173 + +dn: cn=user174,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user174@example.org +cn: user174 +sn: user174 +description: Generated user +uid: user174 +uidNumber: 10174 +gidNumber: 1 +homeDirectory: /home/user174 + +dn: cn=user175,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user175@example.org +cn: user175 +sn: user175 +description: Generated user +uid: user175 +uidNumber: 10175 +gidNumber: 1 +homeDirectory: /home/user175 + +dn: cn=user176,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user176@example.org +cn: user176 +sn: user176 +description: Generated user +uid: user176 +uidNumber: 10176 +gidNumber: 1 +homeDirectory: /home/user176 + +dn: cn=user177,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user177@example.org +cn: user177 +sn: user177 +description: Generated user +uid: user177 +uidNumber: 10177 +gidNumber: 1 +homeDirectory: /home/user177 + +dn: cn=user178,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user178@example.org +cn: user178 +sn: user178 +description: Generated user +uid: user178 +uidNumber: 10178 +gidNumber: 1 +homeDirectory: /home/user178 + +dn: cn=user179,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user179@example.org +cn: user179 +sn: user179 +description: Generated user +uid: user179 +uidNumber: 10179 +gidNumber: 1 +homeDirectory: /home/user179 + +dn: cn=user180,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user180@example.org +cn: user180 +sn: user180 +description: Generated user +uid: user180 +uidNumber: 10180 +gidNumber: 1 +homeDirectory: /home/user180 + +dn: cn=user181,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user181@example.org +cn: user181 +sn: user181 +description: Generated user +uid: user181 +uidNumber: 10181 +gidNumber: 1 +homeDirectory: /home/user181 + +dn: cn=user182,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user182@example.org +cn: user182 +sn: user182 +description: Generated user +uid: user182 +uidNumber: 10182 +gidNumber: 1 +homeDirectory: /home/user182 + +dn: cn=user183,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user183@example.org +cn: user183 +sn: user183 +description: Generated user +uid: user183 +uidNumber: 10183 +gidNumber: 1 +homeDirectory: /home/user183 + +dn: cn=user184,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user184@example.org +cn: user184 +sn: user184 +description: Generated user +uid: user184 +uidNumber: 10184 +gidNumber: 1 +homeDirectory: /home/user184 + +dn: cn=user185,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user185@example.org +cn: user185 +sn: user185 +description: Generated user +uid: user185 +uidNumber: 10185 +gidNumber: 1 +homeDirectory: /home/user185 + +dn: cn=user186,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user186@example.org +cn: user186 +sn: user186 +description: Generated user +uid: user186 +uidNumber: 10186 +gidNumber: 1 +homeDirectory: /home/user186 + +dn: cn=user187,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user187@example.org +cn: user187 +sn: user187 +description: Generated user +uid: user187 +uidNumber: 10187 +gidNumber: 1 +homeDirectory: /home/user187 + +dn: cn=user188,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user188@example.org +cn: user188 +sn: user188 +description: Generated user +uid: user188 +uidNumber: 10188 +gidNumber: 1 +homeDirectory: /home/user188 + +dn: cn=user189,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user189@example.org +cn: user189 +sn: user189 +description: Generated user +uid: user189 +uidNumber: 10189 +gidNumber: 1 +homeDirectory: /home/user189 + +dn: cn=user190,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user190@example.org +cn: user190 +sn: user190 +description: Generated user +uid: user190 +uidNumber: 10190 +gidNumber: 1 +homeDirectory: /home/user190 + +dn: cn=user191,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user191@example.org +cn: user191 +sn: user191 +description: Generated user +uid: user191 +uidNumber: 10191 +gidNumber: 1 +homeDirectory: /home/user191 + +dn: cn=user192,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user192@example.org +cn: user192 +sn: user192 +description: Generated user +uid: user192 +uidNumber: 10192 +gidNumber: 1 +homeDirectory: /home/user192 + +dn: cn=user193,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user193@example.org +cn: user193 +sn: user193 +description: Generated user +uid: user193 +uidNumber: 10193 +gidNumber: 1 +homeDirectory: /home/user193 + +dn: cn=user194,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user194@example.org +cn: user194 +sn: user194 +description: Generated user +uid: user194 +uidNumber: 10194 +gidNumber: 1 +homeDirectory: /home/user194 + +dn: cn=user195,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user195@example.org +cn: user195 +sn: user195 +description: Generated user +uid: user195 +uidNumber: 10195 +gidNumber: 1 +homeDirectory: /home/user195 + +dn: cn=user196,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user196@example.org +cn: user196 +sn: user196 +description: Generated user +uid: user196 +uidNumber: 10196 +gidNumber: 1 +homeDirectory: /home/user196 + +dn: cn=user197,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user197@example.org +cn: user197 +sn: user197 +description: Generated user +uid: user197 +uidNumber: 10197 +gidNumber: 1 +homeDirectory: /home/user197 + +dn: cn=user198,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user198@example.org +cn: user198 +sn: user198 +description: Generated user +uid: user198 +uidNumber: 10198 +gidNumber: 1 +homeDirectory: /home/user198 + +dn: cn=user199,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user199@example.org +cn: user199 +sn: user199 +description: Generated user +uid: user199 +uidNumber: 10199 +gidNumber: 1 +homeDirectory: /home/user199 + +dn: cn=user200,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user200@example.org +cn: user200 +sn: user200 +description: Generated user +uid: user200 +uidNumber: 10200 +gidNumber: 1 +homeDirectory: /home/user200 + +dn: cn=user201,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user201@example.org +cn: user201 +sn: user201 +description: Generated user +uid: user201 +uidNumber: 10201 +gidNumber: 1 +homeDirectory: /home/user201 + +dn: cn=user202,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user202@example.org +cn: user202 +sn: user202 +description: Generated user +uid: user202 +uidNumber: 10202 +gidNumber: 1 +homeDirectory: /home/user202 + +dn: cn=user203,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user203@example.org +cn: user203 +sn: user203 +description: Generated user +uid: user203 +uidNumber: 10203 +gidNumber: 1 +homeDirectory: /home/user203 + +dn: cn=user204,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user204@example.org +cn: user204 +sn: user204 +description: Generated user +uid: user204 +uidNumber: 10204 +gidNumber: 1 +homeDirectory: /home/user204 + +dn: cn=user205,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user205@example.org +cn: user205 +sn: user205 +description: Generated user +uid: user205 +uidNumber: 10205 +gidNumber: 1 +homeDirectory: /home/user205 + +dn: cn=user206,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user206@example.org +cn: user206 +sn: user206 +description: Generated user +uid: user206 +uidNumber: 10206 +gidNumber: 1 +homeDirectory: /home/user206 + +dn: cn=user207,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user207@example.org +cn: user207 +sn: user207 +description: Generated user +uid: user207 +uidNumber: 10207 +gidNumber: 1 +homeDirectory: /home/user207 + +dn: cn=user208,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user208@example.org +cn: user208 +sn: user208 +description: Generated user +uid: user208 +uidNumber: 10208 +gidNumber: 1 +homeDirectory: /home/user208 + +dn: cn=user209,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user209@example.org +cn: user209 +sn: user209 +description: Generated user +uid: user209 +uidNumber: 10209 +gidNumber: 1 +homeDirectory: /home/user209 + +dn: cn=user210,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user210@example.org +cn: user210 +sn: user210 +description: Generated user +uid: user210 +uidNumber: 10210 +gidNumber: 1 +homeDirectory: /home/user210 + +dn: cn=user211,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user211@example.org +cn: user211 +sn: user211 +description: Generated user +uid: user211 +uidNumber: 10211 +gidNumber: 1 +homeDirectory: /home/user211 + +dn: cn=user212,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user212@example.org +cn: user212 +sn: user212 +description: Generated user +uid: user212 +uidNumber: 10212 +gidNumber: 1 +homeDirectory: /home/user212 + +dn: cn=user213,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user213@example.org +cn: user213 +sn: user213 +description: Generated user +uid: user213 +uidNumber: 10213 +gidNumber: 1 +homeDirectory: /home/user213 + +dn: cn=user214,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user214@example.org +cn: user214 +sn: user214 +description: Generated user +uid: user214 +uidNumber: 10214 +gidNumber: 1 +homeDirectory: /home/user214 + +dn: cn=user215,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user215@example.org +cn: user215 +sn: user215 +description: Generated user +uid: user215 +uidNumber: 10215 +gidNumber: 1 +homeDirectory: /home/user215 + +dn: cn=user216,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user216@example.org +cn: user216 +sn: user216 +description: Generated user +uid: user216 +uidNumber: 10216 +gidNumber: 1 +homeDirectory: /home/user216 + +dn: cn=user217,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user217@example.org +cn: user217 +sn: user217 +description: Generated user +uid: user217 +uidNumber: 10217 +gidNumber: 1 +homeDirectory: /home/user217 + +dn: cn=user218,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user218@example.org +cn: user218 +sn: user218 +description: Generated user +uid: user218 +uidNumber: 10218 +gidNumber: 1 +homeDirectory: /home/user218 + +dn: cn=user219,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user219@example.org +cn: user219 +sn: user219 +description: Generated user +uid: user219 +uidNumber: 10219 +gidNumber: 1 +homeDirectory: /home/user219 + +dn: cn=user220,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user220@example.org +cn: user220 +sn: user220 +description: Generated user +uid: user220 +uidNumber: 10220 +gidNumber: 1 +homeDirectory: /home/user220 + +dn: cn=user221,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user221@example.org +cn: user221 +sn: user221 +description: Generated user +uid: user221 +uidNumber: 10221 +gidNumber: 1 +homeDirectory: /home/user221 + +dn: cn=user222,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user222@example.org +cn: user222 +sn: user222 +description: Generated user +uid: user222 +uidNumber: 10222 +gidNumber: 1 +homeDirectory: /home/user222 + +dn: cn=user223,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user223@example.org +cn: user223 +sn: user223 +description: Generated user +uid: user223 +uidNumber: 10223 +gidNumber: 1 +homeDirectory: /home/user223 + +dn: cn=user224,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user224@example.org +cn: user224 +sn: user224 +description: Generated user +uid: user224 +uidNumber: 10224 +gidNumber: 1 +homeDirectory: /home/user224 + +dn: cn=user225,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user225@example.org +cn: user225 +sn: user225 +description: Generated user +uid: user225 +uidNumber: 10225 +gidNumber: 1 +homeDirectory: /home/user225 + +dn: cn=user226,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user226@example.org +cn: user226 +sn: user226 +description: Generated user +uid: user226 +uidNumber: 10226 +gidNumber: 1 +homeDirectory: /home/user226 + +dn: cn=user227,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user227@example.org +cn: user227 +sn: user227 +description: Generated user +uid: user227 +uidNumber: 10227 +gidNumber: 1 +homeDirectory: /home/user227 + +dn: cn=user228,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user228@example.org +cn: user228 +sn: user228 +description: Generated user +uid: user228 +uidNumber: 10228 +gidNumber: 1 +homeDirectory: /home/user228 + +dn: cn=user229,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user229@example.org +cn: user229 +sn: user229 +description: Generated user +uid: user229 +uidNumber: 10229 +gidNumber: 1 +homeDirectory: /home/user229 + +dn: cn=user230,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user230@example.org +cn: user230 +sn: user230 +description: Generated user +uid: user230 +uidNumber: 10230 +gidNumber: 1 +homeDirectory: /home/user230 + +dn: cn=user231,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user231@example.org +cn: user231 +sn: user231 +description: Generated user +uid: user231 +uidNumber: 10231 +gidNumber: 1 +homeDirectory: /home/user231 + +dn: cn=user232,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user232@example.org +cn: user232 +sn: user232 +description: Generated user +uid: user232 +uidNumber: 10232 +gidNumber: 1 +homeDirectory: /home/user232 + +dn: cn=user233,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user233@example.org +cn: user233 +sn: user233 +description: Generated user +uid: user233 +uidNumber: 10233 +gidNumber: 1 +homeDirectory: /home/user233 + +dn: cn=user234,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user234@example.org +cn: user234 +sn: user234 +description: Generated user +uid: user234 +uidNumber: 10234 +gidNumber: 1 +homeDirectory: /home/user234 + +dn: cn=user235,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user235@example.org +cn: user235 +sn: user235 +description: Generated user +uid: user235 +uidNumber: 10235 +gidNumber: 1 +homeDirectory: /home/user235 + +dn: cn=user236,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user236@example.org +cn: user236 +sn: user236 +description: Generated user +uid: user236 +uidNumber: 10236 +gidNumber: 1 +homeDirectory: /home/user236 + +dn: cn=user237,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user237@example.org +cn: user237 +sn: user237 +description: Generated user +uid: user237 +uidNumber: 10237 +gidNumber: 1 +homeDirectory: /home/user237 + +dn: cn=user238,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user238@example.org +cn: user238 +sn: user238 +description: Generated user +uid: user238 +uidNumber: 10238 +gidNumber: 1 +homeDirectory: /home/user238 + +dn: cn=user239,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user239@example.org +cn: user239 +sn: user239 +description: Generated user +uid: user239 +uidNumber: 10239 +gidNumber: 1 +homeDirectory: /home/user239 + +dn: cn=user240,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user240@example.org +cn: user240 +sn: user240 +description: Generated user +uid: user240 +uidNumber: 10240 +gidNumber: 1 +homeDirectory: /home/user240 + +dn: cn=user241,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user241@example.org +cn: user241 +sn: user241 +description: Generated user +uid: user241 +uidNumber: 10241 +gidNumber: 1 +homeDirectory: /home/user241 + +dn: cn=user242,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user242@example.org +cn: user242 +sn: user242 +description: Generated user +uid: user242 +uidNumber: 10242 +gidNumber: 1 +homeDirectory: /home/user242 + +dn: cn=user243,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user243@example.org +cn: user243 +sn: user243 +description: Generated user +uid: user243 +uidNumber: 10243 +gidNumber: 1 +homeDirectory: /home/user243 + +dn: cn=user244,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user244@example.org +cn: user244 +sn: user244 +description: Generated user +uid: user244 +uidNumber: 10244 +gidNumber: 1 +homeDirectory: /home/user244 + +dn: cn=user245,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user245@example.org +cn: user245 +sn: user245 +description: Generated user +uid: user245 +uidNumber: 10245 +gidNumber: 1 +homeDirectory: /home/user245 + +dn: cn=user246,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user246@example.org +cn: user246 +sn: user246 +description: Generated user +uid: user246 +uidNumber: 10246 +gidNumber: 1 +homeDirectory: /home/user246 + +dn: cn=user247,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user247@example.org +cn: user247 +sn: user247 +description: Generated user +uid: user247 +uidNumber: 10247 +gidNumber: 1 +homeDirectory: /home/user247 + +dn: cn=user248,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user248@example.org +cn: user248 +sn: user248 +description: Generated user +uid: user248 +uidNumber: 10248 +gidNumber: 1 +homeDirectory: /home/user248 + +dn: cn=user249,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user249@example.org +cn: user249 +sn: user249 +description: Generated user +uid: user249 +uidNumber: 10249 +gidNumber: 1 +homeDirectory: /home/user249 + +dn: cn=user250,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user250@example.org +cn: user250 +sn: user250 +description: Generated user +uid: user250 +uidNumber: 10250 +gidNumber: 1 +homeDirectory: /home/user250 + +dn: cn=user251,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user251@example.org +cn: user251 +sn: user251 +description: Generated user +uid: user251 +uidNumber: 10251 +gidNumber: 1 +homeDirectory: /home/user251 + +dn: cn=user252,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user252@example.org +cn: user252 +sn: user252 +description: Generated user +uid: user252 +uidNumber: 10252 +gidNumber: 1 +homeDirectory: /home/user252 + +dn: cn=user253,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user253@example.org +cn: user253 +sn: user253 +description: Generated user +uid: user253 +uidNumber: 10253 +gidNumber: 1 +homeDirectory: /home/user253 + +dn: cn=user254,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user254@example.org +cn: user254 +sn: user254 +description: Generated user +uid: user254 +uidNumber: 10254 +gidNumber: 1 +homeDirectory: /home/user254 + +dn: cn=user255,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user255@example.org +cn: user255 +sn: user255 +description: Generated user +uid: user255 +uidNumber: 10255 +gidNumber: 1 +homeDirectory: /home/user255 + +dn: cn=user256,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user256@example.org +cn: user256 +sn: user256 +description: Generated user +uid: user256 +uidNumber: 10256 +gidNumber: 1 +homeDirectory: /home/user256 + +dn: cn=user257,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user257@example.org +cn: user257 +sn: user257 +description: Generated user +uid: user257 +uidNumber: 10257 +gidNumber: 1 +homeDirectory: /home/user257 + +dn: cn=user258,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user258@example.org +cn: user258 +sn: user258 +description: Generated user +uid: user258 +uidNumber: 10258 +gidNumber: 1 +homeDirectory: /home/user258 + +dn: cn=user259,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user259@example.org +cn: user259 +sn: user259 +description: Generated user +uid: user259 +uidNumber: 10259 +gidNumber: 1 +homeDirectory: /home/user259 + +dn: cn=user260,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user260@example.org +cn: user260 +sn: user260 +description: Generated user +uid: user260 +uidNumber: 10260 +gidNumber: 1 +homeDirectory: /home/user260 + +dn: cn=user261,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user261@example.org +cn: user261 +sn: user261 +description: Generated user +uid: user261 +uidNumber: 10261 +gidNumber: 1 +homeDirectory: /home/user261 + +dn: cn=user262,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user262@example.org +cn: user262 +sn: user262 +description: Generated user +uid: user262 +uidNumber: 10262 +gidNumber: 1 +homeDirectory: /home/user262 + +dn: cn=user263,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user263@example.org +cn: user263 +sn: user263 +description: Generated user +uid: user263 +uidNumber: 10263 +gidNumber: 1 +homeDirectory: /home/user263 + +dn: cn=user264,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user264@example.org +cn: user264 +sn: user264 +description: Generated user +uid: user264 +uidNumber: 10264 +gidNumber: 1 +homeDirectory: /home/user264 + +dn: cn=user265,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user265@example.org +cn: user265 +sn: user265 +description: Generated user +uid: user265 +uidNumber: 10265 +gidNumber: 1 +homeDirectory: /home/user265 + +dn: cn=user266,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user266@example.org +cn: user266 +sn: user266 +description: Generated user +uid: user266 +uidNumber: 10266 +gidNumber: 1 +homeDirectory: /home/user266 + +dn: cn=user267,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user267@example.org +cn: user267 +sn: user267 +description: Generated user +uid: user267 +uidNumber: 10267 +gidNumber: 1 +homeDirectory: /home/user267 + +dn: cn=user268,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user268@example.org +cn: user268 +sn: user268 +description: Generated user +uid: user268 +uidNumber: 10268 +gidNumber: 1 +homeDirectory: /home/user268 + +dn: cn=user269,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user269@example.org +cn: user269 +sn: user269 +description: Generated user +uid: user269 +uidNumber: 10269 +gidNumber: 1 +homeDirectory: /home/user269 + +dn: cn=user270,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user270@example.org +cn: user270 +sn: user270 +description: Generated user +uid: user270 +uidNumber: 10270 +gidNumber: 1 +homeDirectory: /home/user270 + +dn: cn=user271,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user271@example.org +cn: user271 +sn: user271 +description: Generated user +uid: user271 +uidNumber: 10271 +gidNumber: 1 +homeDirectory: /home/user271 + +dn: cn=user272,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user272@example.org +cn: user272 +sn: user272 +description: Generated user +uid: user272 +uidNumber: 10272 +gidNumber: 1 +homeDirectory: /home/user272 + +dn: cn=user273,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user273@example.org +cn: user273 +sn: user273 +description: Generated user +uid: user273 +uidNumber: 10273 +gidNumber: 1 +homeDirectory: /home/user273 + +dn: cn=user274,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user274@example.org +cn: user274 +sn: user274 +description: Generated user +uid: user274 +uidNumber: 10274 +gidNumber: 1 +homeDirectory: /home/user274 + +dn: cn=user275,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user275@example.org +cn: user275 +sn: user275 +description: Generated user +uid: user275 +uidNumber: 10275 +gidNumber: 1 +homeDirectory: /home/user275 + +dn: cn=user276,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user276@example.org +cn: user276 +sn: user276 +description: Generated user +uid: user276 +uidNumber: 10276 +gidNumber: 1 +homeDirectory: /home/user276 + +dn: cn=user277,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user277@example.org +cn: user277 +sn: user277 +description: Generated user +uid: user277 +uidNumber: 10277 +gidNumber: 1 +homeDirectory: /home/user277 + +dn: cn=user278,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user278@example.org +cn: user278 +sn: user278 +description: Generated user +uid: user278 +uidNumber: 10278 +gidNumber: 1 +homeDirectory: /home/user278 + +dn: cn=user279,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user279@example.org +cn: user279 +sn: user279 +description: Generated user +uid: user279 +uidNumber: 10279 +gidNumber: 1 +homeDirectory: /home/user279 + +dn: cn=user280,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user280@example.org +cn: user280 +sn: user280 +description: Generated user +uid: user280 +uidNumber: 10280 +gidNumber: 1 +homeDirectory: /home/user280 + +dn: cn=user281,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user281@example.org +cn: user281 +sn: user281 +description: Generated user +uid: user281 +uidNumber: 10281 +gidNumber: 1 +homeDirectory: /home/user281 + +dn: cn=user282,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user282@example.org +cn: user282 +sn: user282 +description: Generated user +uid: user282 +uidNumber: 10282 +gidNumber: 1 +homeDirectory: /home/user282 + +dn: cn=user283,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user283@example.org +cn: user283 +sn: user283 +description: Generated user +uid: user283 +uidNumber: 10283 +gidNumber: 1 +homeDirectory: /home/user283 + +dn: cn=user284,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user284@example.org +cn: user284 +sn: user284 +description: Generated user +uid: user284 +uidNumber: 10284 +gidNumber: 1 +homeDirectory: /home/user284 + +dn: cn=user285,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user285@example.org +cn: user285 +sn: user285 +description: Generated user +uid: user285 +uidNumber: 10285 +gidNumber: 1 +homeDirectory: /home/user285 + +dn: cn=user286,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user286@example.org +cn: user286 +sn: user286 +description: Generated user +uid: user286 +uidNumber: 10286 +gidNumber: 1 +homeDirectory: /home/user286 + +dn: cn=user287,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user287@example.org +cn: user287 +sn: user287 +description: Generated user +uid: user287 +uidNumber: 10287 +gidNumber: 1 +homeDirectory: /home/user287 + +dn: cn=user288,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user288@example.org +cn: user288 +sn: user288 +description: Generated user +uid: user288 +uidNumber: 10288 +gidNumber: 1 +homeDirectory: /home/user288 + +dn: cn=user289,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user289@example.org +cn: user289 +sn: user289 +description: Generated user +uid: user289 +uidNumber: 10289 +gidNumber: 1 +homeDirectory: /home/user289 + +dn: cn=user290,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user290@example.org +cn: user290 +sn: user290 +description: Generated user +uid: user290 +uidNumber: 10290 +gidNumber: 1 +homeDirectory: /home/user290 + +dn: cn=user291,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user291@example.org +cn: user291 +sn: user291 +description: Generated user +uid: user291 +uidNumber: 10291 +gidNumber: 1 +homeDirectory: /home/user291 + +dn: cn=user292,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user292@example.org +cn: user292 +sn: user292 +description: Generated user +uid: user292 +uidNumber: 10292 +gidNumber: 1 +homeDirectory: /home/user292 + +dn: cn=user293,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user293@example.org +cn: user293 +sn: user293 +description: Generated user +uid: user293 +uidNumber: 10293 +gidNumber: 1 +homeDirectory: /home/user293 + +dn: cn=user294,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user294@example.org +cn: user294 +sn: user294 +description: Generated user +uid: user294 +uidNumber: 10294 +gidNumber: 1 +homeDirectory: /home/user294 + +dn: cn=user295,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user295@example.org +cn: user295 +sn: user295 +description: Generated user +uid: user295 +uidNumber: 10295 +gidNumber: 1 +homeDirectory: /home/user295 + +dn: cn=user296,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user296@example.org +cn: user296 +sn: user296 +description: Generated user +uid: user296 +uidNumber: 10296 +gidNumber: 1 +homeDirectory: /home/user296 + +dn: cn=user297,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user297@example.org +cn: user297 +sn: user297 +description: Generated user +uid: user297 +uidNumber: 10297 +gidNumber: 1 +homeDirectory: /home/user297 + +dn: cn=user298,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user298@example.org +cn: user298 +sn: user298 +description: Generated user +uid: user298 +uidNumber: 10298 +gidNumber: 1 +homeDirectory: /home/user298 + +dn: cn=user299,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user299@example.org +cn: user299 +sn: user299 +description: Generated user +uid: user299 +uidNumber: 10299 +gidNumber: 1 +homeDirectory: /home/user299 + +dn: cn=user300,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user300@example.org +cn: user300 +sn: user300 +description: Generated user +uid: user300 +uidNumber: 10300 +gidNumber: 1 +homeDirectory: /home/user300 + +dn: cn=user301,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user301@example.org +cn: user301 +sn: user301 +description: Generated user +uid: user301 +uidNumber: 10301 +gidNumber: 1 +homeDirectory: /home/user301 + +dn: cn=user302,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user302@example.org +cn: user302 +sn: user302 +description: Generated user +uid: user302 +uidNumber: 10302 +gidNumber: 1 +homeDirectory: /home/user302 + +dn: cn=user303,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user303@example.org +cn: user303 +sn: user303 +description: Generated user +uid: user303 +uidNumber: 10303 +gidNumber: 1 +homeDirectory: /home/user303 + +dn: cn=user304,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user304@example.org +cn: user304 +sn: user304 +description: Generated user +uid: user304 +uidNumber: 10304 +gidNumber: 1 +homeDirectory: /home/user304 + +dn: cn=user305,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user305@example.org +cn: user305 +sn: user305 +description: Generated user +uid: user305 +uidNumber: 10305 +gidNumber: 1 +homeDirectory: /home/user305 + +dn: cn=user306,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user306@example.org +cn: user306 +sn: user306 +description: Generated user +uid: user306 +uidNumber: 10306 +gidNumber: 1 +homeDirectory: /home/user306 + +dn: cn=user307,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user307@example.org +cn: user307 +sn: user307 +description: Generated user +uid: user307 +uidNumber: 10307 +gidNumber: 1 +homeDirectory: /home/user307 + +dn: cn=user308,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user308@example.org +cn: user308 +sn: user308 +description: Generated user +uid: user308 +uidNumber: 10308 +gidNumber: 1 +homeDirectory: /home/user308 + +dn: cn=user309,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user309@example.org +cn: user309 +sn: user309 +description: Generated user +uid: user309 +uidNumber: 10309 +gidNumber: 1 +homeDirectory: /home/user309 + +dn: cn=user310,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user310@example.org +cn: user310 +sn: user310 +description: Generated user +uid: user310 +uidNumber: 10310 +gidNumber: 1 +homeDirectory: /home/user310 + +dn: cn=user311,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user311@example.org +cn: user311 +sn: user311 +description: Generated user +uid: user311 +uidNumber: 10311 +gidNumber: 1 +homeDirectory: /home/user311 + +dn: cn=user312,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user312@example.org +cn: user312 +sn: user312 +description: Generated user +uid: user312 +uidNumber: 10312 +gidNumber: 1 +homeDirectory: /home/user312 + +dn: cn=user313,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user313@example.org +cn: user313 +sn: user313 +description: Generated user +uid: user313 +uidNumber: 10313 +gidNumber: 1 +homeDirectory: /home/user313 + +dn: cn=user314,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user314@example.org +cn: user314 +sn: user314 +description: Generated user +uid: user314 +uidNumber: 10314 +gidNumber: 1 +homeDirectory: /home/user314 + +dn: cn=user315,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user315@example.org +cn: user315 +sn: user315 +description: Generated user +uid: user315 +uidNumber: 10315 +gidNumber: 1 +homeDirectory: /home/user315 + +dn: cn=user316,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user316@example.org +cn: user316 +sn: user316 +description: Generated user +uid: user316 +uidNumber: 10316 +gidNumber: 1 +homeDirectory: /home/user316 + +dn: cn=user317,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user317@example.org +cn: user317 +sn: user317 +description: Generated user +uid: user317 +uidNumber: 10317 +gidNumber: 1 +homeDirectory: /home/user317 + +dn: cn=user318,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user318@example.org +cn: user318 +sn: user318 +description: Generated user +uid: user318 +uidNumber: 10318 +gidNumber: 1 +homeDirectory: /home/user318 + +dn: cn=user319,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user319@example.org +cn: user319 +sn: user319 +description: Generated user +uid: user319 +uidNumber: 10319 +gidNumber: 1 +homeDirectory: /home/user319 + +dn: cn=user320,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user320@example.org +cn: user320 +sn: user320 +description: Generated user +uid: user320 +uidNumber: 10320 +gidNumber: 1 +homeDirectory: /home/user320 + +dn: cn=user321,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user321@example.org +cn: user321 +sn: user321 +description: Generated user +uid: user321 +uidNumber: 10321 +gidNumber: 1 +homeDirectory: /home/user321 + +dn: cn=user322,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user322@example.org +cn: user322 +sn: user322 +description: Generated user +uid: user322 +uidNumber: 10322 +gidNumber: 1 +homeDirectory: /home/user322 + +dn: cn=user323,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user323@example.org +cn: user323 +sn: user323 +description: Generated user +uid: user323 +uidNumber: 10323 +gidNumber: 1 +homeDirectory: /home/user323 + +dn: cn=user324,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user324@example.org +cn: user324 +sn: user324 +description: Generated user +uid: user324 +uidNumber: 10324 +gidNumber: 1 +homeDirectory: /home/user324 + +dn: cn=user325,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user325@example.org +cn: user325 +sn: user325 +description: Generated user +uid: user325 +uidNumber: 10325 +gidNumber: 1 +homeDirectory: /home/user325 + +dn: cn=user326,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user326@example.org +cn: user326 +sn: user326 +description: Generated user +uid: user326 +uidNumber: 10326 +gidNumber: 1 +homeDirectory: /home/user326 + +dn: cn=user327,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user327@example.org +cn: user327 +sn: user327 +description: Generated user +uid: user327 +uidNumber: 10327 +gidNumber: 1 +homeDirectory: /home/user327 + +dn: cn=user328,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user328@example.org +cn: user328 +sn: user328 +description: Generated user +uid: user328 +uidNumber: 10328 +gidNumber: 1 +homeDirectory: /home/user328 + +dn: cn=user329,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user329@example.org +cn: user329 +sn: user329 +description: Generated user +uid: user329 +uidNumber: 10329 +gidNumber: 1 +homeDirectory: /home/user329 + +dn: cn=user330,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user330@example.org +cn: user330 +sn: user330 +description: Generated user +uid: user330 +uidNumber: 10330 +gidNumber: 1 +homeDirectory: /home/user330 + +dn: cn=user331,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user331@example.org +cn: user331 +sn: user331 +description: Generated user +uid: user331 +uidNumber: 10331 +gidNumber: 1 +homeDirectory: /home/user331 + +dn: cn=user332,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user332@example.org +cn: user332 +sn: user332 +description: Generated user +uid: user332 +uidNumber: 10332 +gidNumber: 1 +homeDirectory: /home/user332 + +dn: cn=user333,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user333@example.org +cn: user333 +sn: user333 +description: Generated user +uid: user333 +uidNumber: 10333 +gidNumber: 1 +homeDirectory: /home/user333 + +dn: cn=user334,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user334@example.org +cn: user334 +sn: user334 +description: Generated user +uid: user334 +uidNumber: 10334 +gidNumber: 1 +homeDirectory: /home/user334 + +dn: cn=user335,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user335@example.org +cn: user335 +sn: user335 +description: Generated user +uid: user335 +uidNumber: 10335 +gidNumber: 1 +homeDirectory: /home/user335 + +dn: cn=user336,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user336@example.org +cn: user336 +sn: user336 +description: Generated user +uid: user336 +uidNumber: 10336 +gidNumber: 1 +homeDirectory: /home/user336 + +dn: cn=user337,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user337@example.org +cn: user337 +sn: user337 +description: Generated user +uid: user337 +uidNumber: 10337 +gidNumber: 1 +homeDirectory: /home/user337 + +dn: cn=user338,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user338@example.org +cn: user338 +sn: user338 +description: Generated user +uid: user338 +uidNumber: 10338 +gidNumber: 1 +homeDirectory: /home/user338 + +dn: cn=user339,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user339@example.org +cn: user339 +sn: user339 +description: Generated user +uid: user339 +uidNumber: 10339 +gidNumber: 1 +homeDirectory: /home/user339 + +dn: cn=user340,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user340@example.org +cn: user340 +sn: user340 +description: Generated user +uid: user340 +uidNumber: 10340 +gidNumber: 1 +homeDirectory: /home/user340 + +dn: cn=user341,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user341@example.org +cn: user341 +sn: user341 +description: Generated user +uid: user341 +uidNumber: 10341 +gidNumber: 1 +homeDirectory: /home/user341 + +dn: cn=user342,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user342@example.org +cn: user342 +sn: user342 +description: Generated user +uid: user342 +uidNumber: 10342 +gidNumber: 1 +homeDirectory: /home/user342 + +dn: cn=user343,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user343@example.org +cn: user343 +sn: user343 +description: Generated user +uid: user343 +uidNumber: 10343 +gidNumber: 1 +homeDirectory: /home/user343 + +dn: cn=user344,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user344@example.org +cn: user344 +sn: user344 +description: Generated user +uid: user344 +uidNumber: 10344 +gidNumber: 1 +homeDirectory: /home/user344 + +dn: cn=user345,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user345@example.org +cn: user345 +sn: user345 +description: Generated user +uid: user345 +uidNumber: 10345 +gidNumber: 1 +homeDirectory: /home/user345 + +dn: cn=user346,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user346@example.org +cn: user346 +sn: user346 +description: Generated user +uid: user346 +uidNumber: 10346 +gidNumber: 1 +homeDirectory: /home/user346 + +dn: cn=user347,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user347@example.org +cn: user347 +sn: user347 +description: Generated user +uid: user347 +uidNumber: 10347 +gidNumber: 1 +homeDirectory: /home/user347 + +dn: cn=user348,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user348@example.org +cn: user348 +sn: user348 +description: Generated user +uid: user348 +uidNumber: 10348 +gidNumber: 1 +homeDirectory: /home/user348 + +dn: cn=user349,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user349@example.org +cn: user349 +sn: user349 +description: Generated user +uid: user349 +uidNumber: 10349 +gidNumber: 1 +homeDirectory: /home/user349 + +dn: cn=user350,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user350@example.org +cn: user350 +sn: user350 +description: Generated user +uid: user350 +uidNumber: 10350 +gidNumber: 1 +homeDirectory: /home/user350 + +dn: cn=user351,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user351@example.org +cn: user351 +sn: user351 +description: Generated user +uid: user351 +uidNumber: 10351 +gidNumber: 1 +homeDirectory: /home/user351 + +dn: cn=user352,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user352@example.org +cn: user352 +sn: user352 +description: Generated user +uid: user352 +uidNumber: 10352 +gidNumber: 1 +homeDirectory: /home/user352 + +dn: cn=user353,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user353@example.org +cn: user353 +sn: user353 +description: Generated user +uid: user353 +uidNumber: 10353 +gidNumber: 1 +homeDirectory: /home/user353 + +dn: cn=user354,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user354@example.org +cn: user354 +sn: user354 +description: Generated user +uid: user354 +uidNumber: 10354 +gidNumber: 1 +homeDirectory: /home/user354 + +dn: cn=user355,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user355@example.org +cn: user355 +sn: user355 +description: Generated user +uid: user355 +uidNumber: 10355 +gidNumber: 1 +homeDirectory: /home/user355 + +dn: cn=user356,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user356@example.org +cn: user356 +sn: user356 +description: Generated user +uid: user356 +uidNumber: 10356 +gidNumber: 1 +homeDirectory: /home/user356 + +dn: cn=user357,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user357@example.org +cn: user357 +sn: user357 +description: Generated user +uid: user357 +uidNumber: 10357 +gidNumber: 1 +homeDirectory: /home/user357 + +dn: cn=user358,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user358@example.org +cn: user358 +sn: user358 +description: Generated user +uid: user358 +uidNumber: 10358 +gidNumber: 1 +homeDirectory: /home/user358 + +dn: cn=user359,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user359@example.org +cn: user359 +sn: user359 +description: Generated user +uid: user359 +uidNumber: 10359 +gidNumber: 1 +homeDirectory: /home/user359 + +dn: cn=user360,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user360@example.org +cn: user360 +sn: user360 +description: Generated user +uid: user360 +uidNumber: 10360 +gidNumber: 1 +homeDirectory: /home/user360 + +dn: cn=user361,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user361@example.org +cn: user361 +sn: user361 +description: Generated user +uid: user361 +uidNumber: 10361 +gidNumber: 1 +homeDirectory: /home/user361 + +dn: cn=user362,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user362@example.org +cn: user362 +sn: user362 +description: Generated user +uid: user362 +uidNumber: 10362 +gidNumber: 1 +homeDirectory: /home/user362 + +dn: cn=user363,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user363@example.org +cn: user363 +sn: user363 +description: Generated user +uid: user363 +uidNumber: 10363 +gidNumber: 1 +homeDirectory: /home/user363 + +dn: cn=user364,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user364@example.org +cn: user364 +sn: user364 +description: Generated user +uid: user364 +uidNumber: 10364 +gidNumber: 1 +homeDirectory: /home/user364 + +dn: cn=user365,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user365@example.org +cn: user365 +sn: user365 +description: Generated user +uid: user365 +uidNumber: 10365 +gidNumber: 1 +homeDirectory: /home/user365 + +dn: cn=user366,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user366@example.org +cn: user366 +sn: user366 +description: Generated user +uid: user366 +uidNumber: 10366 +gidNumber: 1 +homeDirectory: /home/user366 + +dn: cn=user367,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user367@example.org +cn: user367 +sn: user367 +description: Generated user +uid: user367 +uidNumber: 10367 +gidNumber: 1 +homeDirectory: /home/user367 + +dn: cn=user368,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user368@example.org +cn: user368 +sn: user368 +description: Generated user +uid: user368 +uidNumber: 10368 +gidNumber: 1 +homeDirectory: /home/user368 + +dn: cn=user369,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user369@example.org +cn: user369 +sn: user369 +description: Generated user +uid: user369 +uidNumber: 10369 +gidNumber: 1 +homeDirectory: /home/user369 + +dn: cn=user370,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user370@example.org +cn: user370 +sn: user370 +description: Generated user +uid: user370 +uidNumber: 10370 +gidNumber: 1 +homeDirectory: /home/user370 + +dn: cn=user371,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user371@example.org +cn: user371 +sn: user371 +description: Generated user +uid: user371 +uidNumber: 10371 +gidNumber: 1 +homeDirectory: /home/user371 + +dn: cn=user372,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user372@example.org +cn: user372 +sn: user372 +description: Generated user +uid: user372 +uidNumber: 10372 +gidNumber: 1 +homeDirectory: /home/user372 + +dn: cn=user373,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user373@example.org +cn: user373 +sn: user373 +description: Generated user +uid: user373 +uidNumber: 10373 +gidNumber: 1 +homeDirectory: /home/user373 + +dn: cn=user374,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user374@example.org +cn: user374 +sn: user374 +description: Generated user +uid: user374 +uidNumber: 10374 +gidNumber: 1 +homeDirectory: /home/user374 + +dn: cn=user375,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user375@example.org +cn: user375 +sn: user375 +description: Generated user +uid: user375 +uidNumber: 10375 +gidNumber: 1 +homeDirectory: /home/user375 + +dn: cn=user376,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user376@example.org +cn: user376 +sn: user376 +description: Generated user +uid: user376 +uidNumber: 10376 +gidNumber: 1 +homeDirectory: /home/user376 + +dn: cn=user377,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user377@example.org +cn: user377 +sn: user377 +description: Generated user +uid: user377 +uidNumber: 10377 +gidNumber: 1 +homeDirectory: /home/user377 + +dn: cn=user378,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user378@example.org +cn: user378 +sn: user378 +description: Generated user +uid: user378 +uidNumber: 10378 +gidNumber: 1 +homeDirectory: /home/user378 + +dn: cn=user379,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user379@example.org +cn: user379 +sn: user379 +description: Generated user +uid: user379 +uidNumber: 10379 +gidNumber: 1 +homeDirectory: /home/user379 + +dn: cn=user380,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user380@example.org +cn: user380 +sn: user380 +description: Generated user +uid: user380 +uidNumber: 10380 +gidNumber: 1 +homeDirectory: /home/user380 + +dn: cn=user381,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user381@example.org +cn: user381 +sn: user381 +description: Generated user +uid: user381 +uidNumber: 10381 +gidNumber: 1 +homeDirectory: /home/user381 + +dn: cn=user382,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user382@example.org +cn: user382 +sn: user382 +description: Generated user +uid: user382 +uidNumber: 10382 +gidNumber: 1 +homeDirectory: /home/user382 + +dn: cn=user383,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user383@example.org +cn: user383 +sn: user383 +description: Generated user +uid: user383 +uidNumber: 10383 +gidNumber: 1 +homeDirectory: /home/user383 + +dn: cn=user384,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user384@example.org +cn: user384 +sn: user384 +description: Generated user +uid: user384 +uidNumber: 10384 +gidNumber: 1 +homeDirectory: /home/user384 + +dn: cn=user385,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user385@example.org +cn: user385 +sn: user385 +description: Generated user +uid: user385 +uidNumber: 10385 +gidNumber: 1 +homeDirectory: /home/user385 + +dn: cn=user386,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user386@example.org +cn: user386 +sn: user386 +description: Generated user +uid: user386 +uidNumber: 10386 +gidNumber: 1 +homeDirectory: /home/user386 + +dn: cn=user387,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user387@example.org +cn: user387 +sn: user387 +description: Generated user +uid: user387 +uidNumber: 10387 +gidNumber: 1 +homeDirectory: /home/user387 + +dn: cn=user388,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user388@example.org +cn: user388 +sn: user388 +description: Generated user +uid: user388 +uidNumber: 10388 +gidNumber: 1 +homeDirectory: /home/user388 + +dn: cn=user389,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user389@example.org +cn: user389 +sn: user389 +description: Generated user +uid: user389 +uidNumber: 10389 +gidNumber: 1 +homeDirectory: /home/user389 + +dn: cn=user390,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user390@example.org +cn: user390 +sn: user390 +description: Generated user +uid: user390 +uidNumber: 10390 +gidNumber: 1 +homeDirectory: /home/user390 + +dn: cn=user391,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user391@example.org +cn: user391 +sn: user391 +description: Generated user +uid: user391 +uidNumber: 10391 +gidNumber: 1 +homeDirectory: /home/user391 + +dn: cn=user392,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user392@example.org +cn: user392 +sn: user392 +description: Generated user +uid: user392 +uidNumber: 10392 +gidNumber: 1 +homeDirectory: /home/user392 + +dn: cn=user393,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user393@example.org +cn: user393 +sn: user393 +description: Generated user +uid: user393 +uidNumber: 10393 +gidNumber: 1 +homeDirectory: /home/user393 + +dn: cn=user394,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user394@example.org +cn: user394 +sn: user394 +description: Generated user +uid: user394 +uidNumber: 10394 +gidNumber: 1 +homeDirectory: /home/user394 + +dn: cn=user395,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user395@example.org +cn: user395 +sn: user395 +description: Generated user +uid: user395 +uidNumber: 10395 +gidNumber: 1 +homeDirectory: /home/user395 + +dn: cn=user396,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user396@example.org +cn: user396 +sn: user396 +description: Generated user +uid: user396 +uidNumber: 10396 +gidNumber: 1 +homeDirectory: /home/user396 + +dn: cn=user397,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user397@example.org +cn: user397 +sn: user397 +description: Generated user +uid: user397 +uidNumber: 10397 +gidNumber: 1 +homeDirectory: /home/user397 + +dn: cn=user398,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user398@example.org +cn: user398 +sn: user398 +description: Generated user +uid: user398 +uidNumber: 10398 +gidNumber: 1 +homeDirectory: /home/user398 + +dn: cn=user399,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user399@example.org +cn: user399 +sn: user399 +description: Generated user +uid: user399 +uidNumber: 10399 +gidNumber: 1 +homeDirectory: /home/user399 + +dn: cn=user400,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user400@example.org +cn: user400 +sn: user400 +description: Generated user +uid: user400 +uidNumber: 10400 +gidNumber: 1 +homeDirectory: /home/user400 + +dn: cn=user401,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user401@example.org +cn: user401 +sn: user401 +description: Generated user +uid: user401 +uidNumber: 10401 +gidNumber: 1 +homeDirectory: /home/user401 + +dn: cn=user402,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user402@example.org +cn: user402 +sn: user402 +description: Generated user +uid: user402 +uidNumber: 10402 +gidNumber: 1 +homeDirectory: /home/user402 + +dn: cn=user403,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user403@example.org +cn: user403 +sn: user403 +description: Generated user +uid: user403 +uidNumber: 10403 +gidNumber: 1 +homeDirectory: /home/user403 + +dn: cn=user404,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user404@example.org +cn: user404 +sn: user404 +description: Generated user +uid: user404 +uidNumber: 10404 +gidNumber: 1 +homeDirectory: /home/user404 + +dn: cn=user405,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user405@example.org +cn: user405 +sn: user405 +description: Generated user +uid: user405 +uidNumber: 10405 +gidNumber: 1 +homeDirectory: /home/user405 + +dn: cn=user406,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user406@example.org +cn: user406 +sn: user406 +description: Generated user +uid: user406 +uidNumber: 10406 +gidNumber: 1 +homeDirectory: /home/user406 + +dn: cn=user407,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user407@example.org +cn: user407 +sn: user407 +description: Generated user +uid: user407 +uidNumber: 10407 +gidNumber: 1 +homeDirectory: /home/user407 + +dn: cn=user408,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user408@example.org +cn: user408 +sn: user408 +description: Generated user +uid: user408 +uidNumber: 10408 +gidNumber: 1 +homeDirectory: /home/user408 + +dn: cn=user409,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user409@example.org +cn: user409 +sn: user409 +description: Generated user +uid: user409 +uidNumber: 10409 +gidNumber: 1 +homeDirectory: /home/user409 + +dn: cn=user410,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user410@example.org +cn: user410 +sn: user410 +description: Generated user +uid: user410 +uidNumber: 10410 +gidNumber: 1 +homeDirectory: /home/user410 + +dn: cn=user411,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user411@example.org +cn: user411 +sn: user411 +description: Generated user +uid: user411 +uidNumber: 10411 +gidNumber: 1 +homeDirectory: /home/user411 + +dn: cn=user412,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user412@example.org +cn: user412 +sn: user412 +description: Generated user +uid: user412 +uidNumber: 10412 +gidNumber: 1 +homeDirectory: /home/user412 + +dn: cn=user413,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user413@example.org +cn: user413 +sn: user413 +description: Generated user +uid: user413 +uidNumber: 10413 +gidNumber: 1 +homeDirectory: /home/user413 + +dn: cn=user414,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user414@example.org +cn: user414 +sn: user414 +description: Generated user +uid: user414 +uidNumber: 10414 +gidNumber: 1 +homeDirectory: /home/user414 + +dn: cn=user415,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user415@example.org +cn: user415 +sn: user415 +description: Generated user +uid: user415 +uidNumber: 10415 +gidNumber: 1 +homeDirectory: /home/user415 + +dn: cn=user416,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user416@example.org +cn: user416 +sn: user416 +description: Generated user +uid: user416 +uidNumber: 10416 +gidNumber: 1 +homeDirectory: /home/user416 + +dn: cn=user417,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user417@example.org +cn: user417 +sn: user417 +description: Generated user +uid: user417 +uidNumber: 10417 +gidNumber: 1 +homeDirectory: /home/user417 + +dn: cn=user418,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user418@example.org +cn: user418 +sn: user418 +description: Generated user +uid: user418 +uidNumber: 10418 +gidNumber: 1 +homeDirectory: /home/user418 + +dn: cn=user419,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user419@example.org +cn: user419 +sn: user419 +description: Generated user +uid: user419 +uidNumber: 10419 +gidNumber: 1 +homeDirectory: /home/user419 + +dn: cn=user420,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user420@example.org +cn: user420 +sn: user420 +description: Generated user +uid: user420 +uidNumber: 10420 +gidNumber: 1 +homeDirectory: /home/user420 + +dn: cn=user421,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user421@example.org +cn: user421 +sn: user421 +description: Generated user +uid: user421 +uidNumber: 10421 +gidNumber: 1 +homeDirectory: /home/user421 + +dn: cn=user422,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user422@example.org +cn: user422 +sn: user422 +description: Generated user +uid: user422 +uidNumber: 10422 +gidNumber: 1 +homeDirectory: /home/user422 + +dn: cn=user423,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user423@example.org +cn: user423 +sn: user423 +description: Generated user +uid: user423 +uidNumber: 10423 +gidNumber: 1 +homeDirectory: /home/user423 + +dn: cn=user424,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user424@example.org +cn: user424 +sn: user424 +description: Generated user +uid: user424 +uidNumber: 10424 +gidNumber: 1 +homeDirectory: /home/user424 + +dn: cn=user425,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user425@example.org +cn: user425 +sn: user425 +description: Generated user +uid: user425 +uidNumber: 10425 +gidNumber: 1 +homeDirectory: /home/user425 + +dn: cn=user426,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user426@example.org +cn: user426 +sn: user426 +description: Generated user +uid: user426 +uidNumber: 10426 +gidNumber: 1 +homeDirectory: /home/user426 + +dn: cn=user427,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user427@example.org +cn: user427 +sn: user427 +description: Generated user +uid: user427 +uidNumber: 10427 +gidNumber: 1 +homeDirectory: /home/user427 + +dn: cn=user428,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user428@example.org +cn: user428 +sn: user428 +description: Generated user +uid: user428 +uidNumber: 10428 +gidNumber: 1 +homeDirectory: /home/user428 + +dn: cn=user429,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user429@example.org +cn: user429 +sn: user429 +description: Generated user +uid: user429 +uidNumber: 10429 +gidNumber: 1 +homeDirectory: /home/user429 + +dn: cn=user430,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user430@example.org +cn: user430 +sn: user430 +description: Generated user +uid: user430 +uidNumber: 10430 +gidNumber: 1 +homeDirectory: /home/user430 + +dn: cn=user431,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user431@example.org +cn: user431 +sn: user431 +description: Generated user +uid: user431 +uidNumber: 10431 +gidNumber: 1 +homeDirectory: /home/user431 + +dn: cn=user432,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user432@example.org +cn: user432 +sn: user432 +description: Generated user +uid: user432 +uidNumber: 10432 +gidNumber: 1 +homeDirectory: /home/user432 + +dn: cn=user433,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user433@example.org +cn: user433 +sn: user433 +description: Generated user +uid: user433 +uidNumber: 10433 +gidNumber: 1 +homeDirectory: /home/user433 + +dn: cn=user434,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user434@example.org +cn: user434 +sn: user434 +description: Generated user +uid: user434 +uidNumber: 10434 +gidNumber: 1 +homeDirectory: /home/user434 + +dn: cn=user435,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user435@example.org +cn: user435 +sn: user435 +description: Generated user +uid: user435 +uidNumber: 10435 +gidNumber: 1 +homeDirectory: /home/user435 + +dn: cn=user436,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user436@example.org +cn: user436 +sn: user436 +description: Generated user +uid: user436 +uidNumber: 10436 +gidNumber: 1 +homeDirectory: /home/user436 + +dn: cn=user437,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user437@example.org +cn: user437 +sn: user437 +description: Generated user +uid: user437 +uidNumber: 10437 +gidNumber: 1 +homeDirectory: /home/user437 + +dn: cn=user438,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user438@example.org +cn: user438 +sn: user438 +description: Generated user +uid: user438 +uidNumber: 10438 +gidNumber: 1 +homeDirectory: /home/user438 + +dn: cn=user439,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user439@example.org +cn: user439 +sn: user439 +description: Generated user +uid: user439 +uidNumber: 10439 +gidNumber: 1 +homeDirectory: /home/user439 + +dn: cn=user440,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user440@example.org +cn: user440 +sn: user440 +description: Generated user +uid: user440 +uidNumber: 10440 +gidNumber: 1 +homeDirectory: /home/user440 + +dn: cn=user441,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user441@example.org +cn: user441 +sn: user441 +description: Generated user +uid: user441 +uidNumber: 10441 +gidNumber: 1 +homeDirectory: /home/user441 + +dn: cn=user442,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user442@example.org +cn: user442 +sn: user442 +description: Generated user +uid: user442 +uidNumber: 10442 +gidNumber: 1 +homeDirectory: /home/user442 + +dn: cn=user443,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user443@example.org +cn: user443 +sn: user443 +description: Generated user +uid: user443 +uidNumber: 10443 +gidNumber: 1 +homeDirectory: /home/user443 + +dn: cn=user444,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user444@example.org +cn: user444 +sn: user444 +description: Generated user +uid: user444 +uidNumber: 10444 +gidNumber: 1 +homeDirectory: /home/user444 + +dn: cn=user445,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user445@example.org +cn: user445 +sn: user445 +description: Generated user +uid: user445 +uidNumber: 10445 +gidNumber: 1 +homeDirectory: /home/user445 + +dn: cn=user446,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user446@example.org +cn: user446 +sn: user446 +description: Generated user +uid: user446 +uidNumber: 10446 +gidNumber: 1 +homeDirectory: /home/user446 + +dn: cn=user447,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user447@example.org +cn: user447 +sn: user447 +description: Generated user +uid: user447 +uidNumber: 10447 +gidNumber: 1 +homeDirectory: /home/user447 + +dn: cn=user448,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user448@example.org +cn: user448 +sn: user448 +description: Generated user +uid: user448 +uidNumber: 10448 +gidNumber: 1 +homeDirectory: /home/user448 + +dn: cn=user449,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user449@example.org +cn: user449 +sn: user449 +description: Generated user +uid: user449 +uidNumber: 10449 +gidNumber: 1 +homeDirectory: /home/user449 + +dn: cn=user450,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user450@example.org +cn: user450 +sn: user450 +description: Generated user +uid: user450 +uidNumber: 10450 +gidNumber: 1 +homeDirectory: /home/user450 + +dn: cn=user451,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user451@example.org +cn: user451 +sn: user451 +description: Generated user +uid: user451 +uidNumber: 10451 +gidNumber: 1 +homeDirectory: /home/user451 + +dn: cn=user452,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user452@example.org +cn: user452 +sn: user452 +description: Generated user +uid: user452 +uidNumber: 10452 +gidNumber: 1 +homeDirectory: /home/user452 + +dn: cn=user453,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user453@example.org +cn: user453 +sn: user453 +description: Generated user +uid: user453 +uidNumber: 10453 +gidNumber: 1 +homeDirectory: /home/user453 + +dn: cn=user454,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user454@example.org +cn: user454 +sn: user454 +description: Generated user +uid: user454 +uidNumber: 10454 +gidNumber: 1 +homeDirectory: /home/user454 + +dn: cn=user455,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user455@example.org +cn: user455 +sn: user455 +description: Generated user +uid: user455 +uidNumber: 10455 +gidNumber: 1 +homeDirectory: /home/user455 + +dn: cn=user456,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user456@example.org +cn: user456 +sn: user456 +description: Generated user +uid: user456 +uidNumber: 10456 +gidNumber: 1 +homeDirectory: /home/user456 + +dn: cn=user457,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user457@example.org +cn: user457 +sn: user457 +description: Generated user +uid: user457 +uidNumber: 10457 +gidNumber: 1 +homeDirectory: /home/user457 + +dn: cn=user458,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user458@example.org +cn: user458 +sn: user458 +description: Generated user +uid: user458 +uidNumber: 10458 +gidNumber: 1 +homeDirectory: /home/user458 + +dn: cn=user459,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user459@example.org +cn: user459 +sn: user459 +description: Generated user +uid: user459 +uidNumber: 10459 +gidNumber: 1 +homeDirectory: /home/user459 + +dn: cn=user460,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user460@example.org +cn: user460 +sn: user460 +description: Generated user +uid: user460 +uidNumber: 10460 +gidNumber: 1 +homeDirectory: /home/user460 + +dn: cn=user461,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user461@example.org +cn: user461 +sn: user461 +description: Generated user +uid: user461 +uidNumber: 10461 +gidNumber: 1 +homeDirectory: /home/user461 + +dn: cn=user462,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user462@example.org +cn: user462 +sn: user462 +description: Generated user +uid: user462 +uidNumber: 10462 +gidNumber: 1 +homeDirectory: /home/user462 + +dn: cn=user463,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user463@example.org +cn: user463 +sn: user463 +description: Generated user +uid: user463 +uidNumber: 10463 +gidNumber: 1 +homeDirectory: /home/user463 + +dn: cn=user464,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user464@example.org +cn: user464 +sn: user464 +description: Generated user +uid: user464 +uidNumber: 10464 +gidNumber: 1 +homeDirectory: /home/user464 + +dn: cn=user465,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user465@example.org +cn: user465 +sn: user465 +description: Generated user +uid: user465 +uidNumber: 10465 +gidNumber: 1 +homeDirectory: /home/user465 + +dn: cn=user466,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user466@example.org +cn: user466 +sn: user466 +description: Generated user +uid: user466 +uidNumber: 10466 +gidNumber: 1 +homeDirectory: /home/user466 + +dn: cn=user467,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user467@example.org +cn: user467 +sn: user467 +description: Generated user +uid: user467 +uidNumber: 10467 +gidNumber: 1 +homeDirectory: /home/user467 + +dn: cn=user468,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user468@example.org +cn: user468 +sn: user468 +description: Generated user +uid: user468 +uidNumber: 10468 +gidNumber: 1 +homeDirectory: /home/user468 + +dn: cn=user469,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user469@example.org +cn: user469 +sn: user469 +description: Generated user +uid: user469 +uidNumber: 10469 +gidNumber: 1 +homeDirectory: /home/user469 + +dn: cn=user470,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user470@example.org +cn: user470 +sn: user470 +description: Generated user +uid: user470 +uidNumber: 10470 +gidNumber: 1 +homeDirectory: /home/user470 + +dn: cn=user471,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user471@example.org +cn: user471 +sn: user471 +description: Generated user +uid: user471 +uidNumber: 10471 +gidNumber: 1 +homeDirectory: /home/user471 + +dn: cn=user472,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user472@example.org +cn: user472 +sn: user472 +description: Generated user +uid: user472 +uidNumber: 10472 +gidNumber: 1 +homeDirectory: /home/user472 + +dn: cn=user473,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user473@example.org +cn: user473 +sn: user473 +description: Generated user +uid: user473 +uidNumber: 10473 +gidNumber: 1 +homeDirectory: /home/user473 + +dn: cn=user474,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user474@example.org +cn: user474 +sn: user474 +description: Generated user +uid: user474 +uidNumber: 10474 +gidNumber: 1 +homeDirectory: /home/user474 + +dn: cn=user475,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user475@example.org +cn: user475 +sn: user475 +description: Generated user +uid: user475 +uidNumber: 10475 +gidNumber: 1 +homeDirectory: /home/user475 + +dn: cn=user476,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user476@example.org +cn: user476 +sn: user476 +description: Generated user +uid: user476 +uidNumber: 10476 +gidNumber: 1 +homeDirectory: /home/user476 + +dn: cn=user477,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user477@example.org +cn: user477 +sn: user477 +description: Generated user +uid: user477 +uidNumber: 10477 +gidNumber: 1 +homeDirectory: /home/user477 + +dn: cn=user478,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user478@example.org +cn: user478 +sn: user478 +description: Generated user +uid: user478 +uidNumber: 10478 +gidNumber: 1 +homeDirectory: /home/user478 + +dn: cn=user479,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user479@example.org +cn: user479 +sn: user479 +description: Generated user +uid: user479 +uidNumber: 10479 +gidNumber: 1 +homeDirectory: /home/user479 + +dn: cn=user480,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user480@example.org +cn: user480 +sn: user480 +description: Generated user +uid: user480 +uidNumber: 10480 +gidNumber: 1 +homeDirectory: /home/user480 + +dn: cn=user481,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user481@example.org +cn: user481 +sn: user481 +description: Generated user +uid: user481 +uidNumber: 10481 +gidNumber: 1 +homeDirectory: /home/user481 + +dn: cn=user482,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user482@example.org +cn: user482 +sn: user482 +description: Generated user +uid: user482 +uidNumber: 10482 +gidNumber: 1 +homeDirectory: /home/user482 + +dn: cn=user483,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user483@example.org +cn: user483 +sn: user483 +description: Generated user +uid: user483 +uidNumber: 10483 +gidNumber: 1 +homeDirectory: /home/user483 + +dn: cn=user484,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user484@example.org +cn: user484 +sn: user484 +description: Generated user +uid: user484 +uidNumber: 10484 +gidNumber: 1 +homeDirectory: /home/user484 + +dn: cn=user485,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user485@example.org +cn: user485 +sn: user485 +description: Generated user +uid: user485 +uidNumber: 10485 +gidNumber: 1 +homeDirectory: /home/user485 + +dn: cn=user486,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user486@example.org +cn: user486 +sn: user486 +description: Generated user +uid: user486 +uidNumber: 10486 +gidNumber: 1 +homeDirectory: /home/user486 + +dn: cn=user487,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user487@example.org +cn: user487 +sn: user487 +description: Generated user +uid: user487 +uidNumber: 10487 +gidNumber: 1 +homeDirectory: /home/user487 + +dn: cn=user488,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user488@example.org +cn: user488 +sn: user488 +description: Generated user +uid: user488 +uidNumber: 10488 +gidNumber: 1 +homeDirectory: /home/user488 + +dn: cn=user489,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user489@example.org +cn: user489 +sn: user489 +description: Generated user +uid: user489 +uidNumber: 10489 +gidNumber: 1 +homeDirectory: /home/user489 + +dn: cn=user490,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user490@example.org +cn: user490 +sn: user490 +description: Generated user +uid: user490 +uidNumber: 10490 +gidNumber: 1 +homeDirectory: /home/user490 + +dn: cn=user491,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user491@example.org +cn: user491 +sn: user491 +description: Generated user +uid: user491 +uidNumber: 10491 +gidNumber: 1 +homeDirectory: /home/user491 + +dn: cn=user492,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user492@example.org +cn: user492 +sn: user492 +description: Generated user +uid: user492 +uidNumber: 10492 +gidNumber: 1 +homeDirectory: /home/user492 + +dn: cn=user493,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user493@example.org +cn: user493 +sn: user493 +description: Generated user +uid: user493 +uidNumber: 10493 +gidNumber: 1 +homeDirectory: /home/user493 + +dn: cn=user494,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user494@example.org +cn: user494 +sn: user494 +description: Generated user +uid: user494 +uidNumber: 10494 +gidNumber: 1 +homeDirectory: /home/user494 + +dn: cn=user495,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user495@example.org +cn: user495 +sn: user495 +description: Generated user +uid: user495 +uidNumber: 10495 +gidNumber: 1 +homeDirectory: /home/user495 + +dn: cn=user496,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user496@example.org +cn: user496 +sn: user496 +description: Generated user +uid: user496 +uidNumber: 10496 +gidNumber: 1 +homeDirectory: /home/user496 + +dn: cn=user497,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user497@example.org +cn: user497 +sn: user497 +description: Generated user +uid: user497 +uidNumber: 10497 +gidNumber: 1 +homeDirectory: /home/user497 + +dn: cn=user498,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user498@example.org +cn: user498 +sn: user498 +description: Generated user +uid: user498 +uidNumber: 10498 +gidNumber: 1 +homeDirectory: /home/user498 + +dn: cn=user499,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user499@example.org +cn: user499 +sn: user499 +description: Generated user +uid: user499 +uidNumber: 10499 +gidNumber: 1 +homeDirectory: /home/user499 + +dn: cn=user500,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user500@example.org +cn: user500 +sn: user500 +description: Generated user +uid: user500 +uidNumber: 10500 +gidNumber: 1 +homeDirectory: /home/user500 + +dn: cn=user501,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user501@example.org +cn: user501 +sn: user501 +description: Generated user +uid: user501 +uidNumber: 10501 +gidNumber: 1 +homeDirectory: /home/user501 + +dn: cn=user502,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user502@example.org +cn: user502 +sn: user502 +description: Generated user +uid: user502 +uidNumber: 10502 +gidNumber: 1 +homeDirectory: /home/user502 + +dn: cn=user503,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user503@example.org +cn: user503 +sn: user503 +description: Generated user +uid: user503 +uidNumber: 10503 +gidNumber: 1 +homeDirectory: /home/user503 + +dn: cn=user504,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user504@example.org +cn: user504 +sn: user504 +description: Generated user +uid: user504 +uidNumber: 10504 +gidNumber: 1 +homeDirectory: /home/user504 + +dn: cn=user505,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user505@example.org +cn: user505 +sn: user505 +description: Generated user +uid: user505 +uidNumber: 10505 +gidNumber: 1 +homeDirectory: /home/user505 + +dn: cn=user506,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user506@example.org +cn: user506 +sn: user506 +description: Generated user +uid: user506 +uidNumber: 10506 +gidNumber: 1 +homeDirectory: /home/user506 + +dn: cn=user507,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user507@example.org +cn: user507 +sn: user507 +description: Generated user +uid: user507 +uidNumber: 10507 +gidNumber: 1 +homeDirectory: /home/user507 + +dn: cn=user508,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user508@example.org +cn: user508 +sn: user508 +description: Generated user +uid: user508 +uidNumber: 10508 +gidNumber: 1 +homeDirectory: /home/user508 + +dn: cn=user509,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user509@example.org +cn: user509 +sn: user509 +description: Generated user +uid: user509 +uidNumber: 10509 +gidNumber: 1 +homeDirectory: /home/user509 + +dn: cn=user510,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user510@example.org +cn: user510 +sn: user510 +description: Generated user +uid: user510 +uidNumber: 10510 +gidNumber: 1 +homeDirectory: /home/user510 + +dn: cn=user511,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user511@example.org +cn: user511 +sn: user511 +description: Generated user +uid: user511 +uidNumber: 10511 +gidNumber: 1 +homeDirectory: /home/user511 + +dn: cn=user512,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user512@example.org +cn: user512 +sn: user512 +description: Generated user +uid: user512 +uidNumber: 10512 +gidNumber: 1 +homeDirectory: /home/user512 + +dn: cn=user513,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user513@example.org +cn: user513 +sn: user513 +description: Generated user +uid: user513 +uidNumber: 10513 +gidNumber: 1 +homeDirectory: /home/user513 + +dn: cn=user514,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user514@example.org +cn: user514 +sn: user514 +description: Generated user +uid: user514 +uidNumber: 10514 +gidNumber: 1 +homeDirectory: /home/user514 + +dn: cn=user515,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user515@example.org +cn: user515 +sn: user515 +description: Generated user +uid: user515 +uidNumber: 10515 +gidNumber: 1 +homeDirectory: /home/user515 + +dn: cn=user516,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user516@example.org +cn: user516 +sn: user516 +description: Generated user +uid: user516 +uidNumber: 10516 +gidNumber: 1 +homeDirectory: /home/user516 + +dn: cn=user517,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user517@example.org +cn: user517 +sn: user517 +description: Generated user +uid: user517 +uidNumber: 10517 +gidNumber: 1 +homeDirectory: /home/user517 + +dn: cn=user518,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user518@example.org +cn: user518 +sn: user518 +description: Generated user +uid: user518 +uidNumber: 10518 +gidNumber: 1 +homeDirectory: /home/user518 + +dn: cn=user519,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user519@example.org +cn: user519 +sn: user519 +description: Generated user +uid: user519 +uidNumber: 10519 +gidNumber: 1 +homeDirectory: /home/user519 + +dn: cn=user520,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user520@example.org +cn: user520 +sn: user520 +description: Generated user +uid: user520 +uidNumber: 10520 +gidNumber: 1 +homeDirectory: /home/user520 + +dn: cn=user521,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user521@example.org +cn: user521 +sn: user521 +description: Generated user +uid: user521 +uidNumber: 10521 +gidNumber: 1 +homeDirectory: /home/user521 + +dn: cn=user522,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user522@example.org +cn: user522 +sn: user522 +description: Generated user +uid: user522 +uidNumber: 10522 +gidNumber: 1 +homeDirectory: /home/user522 + +dn: cn=user523,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user523@example.org +cn: user523 +sn: user523 +description: Generated user +uid: user523 +uidNumber: 10523 +gidNumber: 1 +homeDirectory: /home/user523 + +dn: cn=user524,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user524@example.org +cn: user524 +sn: user524 +description: Generated user +uid: user524 +uidNumber: 10524 +gidNumber: 1 +homeDirectory: /home/user524 + +dn: cn=user525,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user525@example.org +cn: user525 +sn: user525 +description: Generated user +uid: user525 +uidNumber: 10525 +gidNumber: 1 +homeDirectory: /home/user525 + +dn: cn=user526,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user526@example.org +cn: user526 +sn: user526 +description: Generated user +uid: user526 +uidNumber: 10526 +gidNumber: 1 +homeDirectory: /home/user526 + +dn: cn=user527,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user527@example.org +cn: user527 +sn: user527 +description: Generated user +uid: user527 +uidNumber: 10527 +gidNumber: 1 +homeDirectory: /home/user527 + +dn: cn=user528,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user528@example.org +cn: user528 +sn: user528 +description: Generated user +uid: user528 +uidNumber: 10528 +gidNumber: 1 +homeDirectory: /home/user528 + +dn: cn=user529,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user529@example.org +cn: user529 +sn: user529 +description: Generated user +uid: user529 +uidNumber: 10529 +gidNumber: 1 +homeDirectory: /home/user529 + +dn: cn=user530,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user530@example.org +cn: user530 +sn: user530 +description: Generated user +uid: user530 +uidNumber: 10530 +gidNumber: 1 +homeDirectory: /home/user530 + +dn: cn=user531,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user531@example.org +cn: user531 +sn: user531 +description: Generated user +uid: user531 +uidNumber: 10531 +gidNumber: 1 +homeDirectory: /home/user531 + +dn: cn=user532,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user532@example.org +cn: user532 +sn: user532 +description: Generated user +uid: user532 +uidNumber: 10532 +gidNumber: 1 +homeDirectory: /home/user532 + +dn: cn=user533,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user533@example.org +cn: user533 +sn: user533 +description: Generated user +uid: user533 +uidNumber: 10533 +gidNumber: 1 +homeDirectory: /home/user533 + +dn: cn=user534,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user534@example.org +cn: user534 +sn: user534 +description: Generated user +uid: user534 +uidNumber: 10534 +gidNumber: 1 +homeDirectory: /home/user534 + +dn: cn=user535,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user535@example.org +cn: user535 +sn: user535 +description: Generated user +uid: user535 +uidNumber: 10535 +gidNumber: 1 +homeDirectory: /home/user535 + +dn: cn=user536,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user536@example.org +cn: user536 +sn: user536 +description: Generated user +uid: user536 +uidNumber: 10536 +gidNumber: 1 +homeDirectory: /home/user536 + +dn: cn=user537,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user537@example.org +cn: user537 +sn: user537 +description: Generated user +uid: user537 +uidNumber: 10537 +gidNumber: 1 +homeDirectory: /home/user537 + +dn: cn=user538,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user538@example.org +cn: user538 +sn: user538 +description: Generated user +uid: user538 +uidNumber: 10538 +gidNumber: 1 +homeDirectory: /home/user538 + +dn: cn=user539,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user539@example.org +cn: user539 +sn: user539 +description: Generated user +uid: user539 +uidNumber: 10539 +gidNumber: 1 +homeDirectory: /home/user539 + +dn: cn=user540,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user540@example.org +cn: user540 +sn: user540 +description: Generated user +uid: user540 +uidNumber: 10540 +gidNumber: 1 +homeDirectory: /home/user540 + +dn: cn=user541,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user541@example.org +cn: user541 +sn: user541 +description: Generated user +uid: user541 +uidNumber: 10541 +gidNumber: 1 +homeDirectory: /home/user541 + +dn: cn=user542,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user542@example.org +cn: user542 +sn: user542 +description: Generated user +uid: user542 +uidNumber: 10542 +gidNumber: 1 +homeDirectory: /home/user542 + +dn: cn=user543,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user543@example.org +cn: user543 +sn: user543 +description: Generated user +uid: user543 +uidNumber: 10543 +gidNumber: 1 +homeDirectory: /home/user543 + +dn: cn=user544,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user544@example.org +cn: user544 +sn: user544 +description: Generated user +uid: user544 +uidNumber: 10544 +gidNumber: 1 +homeDirectory: /home/user544 + +dn: cn=user545,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user545@example.org +cn: user545 +sn: user545 +description: Generated user +uid: user545 +uidNumber: 10545 +gidNumber: 1 +homeDirectory: /home/user545 + +dn: cn=user546,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user546@example.org +cn: user546 +sn: user546 +description: Generated user +uid: user546 +uidNumber: 10546 +gidNumber: 1 +homeDirectory: /home/user546 + +dn: cn=user547,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user547@example.org +cn: user547 +sn: user547 +description: Generated user +uid: user547 +uidNumber: 10547 +gidNumber: 1 +homeDirectory: /home/user547 + +dn: cn=user548,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user548@example.org +cn: user548 +sn: user548 +description: Generated user +uid: user548 +uidNumber: 10548 +gidNumber: 1 +homeDirectory: /home/user548 + +dn: cn=user549,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user549@example.org +cn: user549 +sn: user549 +description: Generated user +uid: user549 +uidNumber: 10549 +gidNumber: 1 +homeDirectory: /home/user549 + +dn: cn=user550,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user550@example.org +cn: user550 +sn: user550 +description: Generated user +uid: user550 +uidNumber: 10550 +gidNumber: 1 +homeDirectory: /home/user550 + +dn: cn=user551,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user551@example.org +cn: user551 +sn: user551 +description: Generated user +uid: user551 +uidNumber: 10551 +gidNumber: 1 +homeDirectory: /home/user551 + +dn: cn=user552,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user552@example.org +cn: user552 +sn: user552 +description: Generated user +uid: user552 +uidNumber: 10552 +gidNumber: 1 +homeDirectory: /home/user552 + +dn: cn=user553,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user553@example.org +cn: user553 +sn: user553 +description: Generated user +uid: user553 +uidNumber: 10553 +gidNumber: 1 +homeDirectory: /home/user553 + +dn: cn=user554,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user554@example.org +cn: user554 +sn: user554 +description: Generated user +uid: user554 +uidNumber: 10554 +gidNumber: 1 +homeDirectory: /home/user554 + +dn: cn=user555,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user555@example.org +cn: user555 +sn: user555 +description: Generated user +uid: user555 +uidNumber: 10555 +gidNumber: 1 +homeDirectory: /home/user555 + +dn: cn=user556,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user556@example.org +cn: user556 +sn: user556 +description: Generated user +uid: user556 +uidNumber: 10556 +gidNumber: 1 +homeDirectory: /home/user556 + +dn: cn=user557,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user557@example.org +cn: user557 +sn: user557 +description: Generated user +uid: user557 +uidNumber: 10557 +gidNumber: 1 +homeDirectory: /home/user557 + +dn: cn=user558,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user558@example.org +cn: user558 +sn: user558 +description: Generated user +uid: user558 +uidNumber: 10558 +gidNumber: 1 +homeDirectory: /home/user558 + +dn: cn=user559,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user559@example.org +cn: user559 +sn: user559 +description: Generated user +uid: user559 +uidNumber: 10559 +gidNumber: 1 +homeDirectory: /home/user559 + +dn: cn=user560,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user560@example.org +cn: user560 +sn: user560 +description: Generated user +uid: user560 +uidNumber: 10560 +gidNumber: 1 +homeDirectory: /home/user560 + +dn: cn=user561,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user561@example.org +cn: user561 +sn: user561 +description: Generated user +uid: user561 +uidNumber: 10561 +gidNumber: 1 +homeDirectory: /home/user561 + +dn: cn=user562,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user562@example.org +cn: user562 +sn: user562 +description: Generated user +uid: user562 +uidNumber: 10562 +gidNumber: 1 +homeDirectory: /home/user562 + +dn: cn=user563,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user563@example.org +cn: user563 +sn: user563 +description: Generated user +uid: user563 +uidNumber: 10563 +gidNumber: 1 +homeDirectory: /home/user563 + +dn: cn=user564,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user564@example.org +cn: user564 +sn: user564 +description: Generated user +uid: user564 +uidNumber: 10564 +gidNumber: 1 +homeDirectory: /home/user564 + +dn: cn=user565,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user565@example.org +cn: user565 +sn: user565 +description: Generated user +uid: user565 +uidNumber: 10565 +gidNumber: 1 +homeDirectory: /home/user565 + +dn: cn=user566,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user566@example.org +cn: user566 +sn: user566 +description: Generated user +uid: user566 +uidNumber: 10566 +gidNumber: 1 +homeDirectory: /home/user566 + +dn: cn=user567,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user567@example.org +cn: user567 +sn: user567 +description: Generated user +uid: user567 +uidNumber: 10567 +gidNumber: 1 +homeDirectory: /home/user567 + +dn: cn=user568,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user568@example.org +cn: user568 +sn: user568 +description: Generated user +uid: user568 +uidNumber: 10568 +gidNumber: 1 +homeDirectory: /home/user568 + +dn: cn=user569,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user569@example.org +cn: user569 +sn: user569 +description: Generated user +uid: user569 +uidNumber: 10569 +gidNumber: 1 +homeDirectory: /home/user569 + +dn: cn=user570,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user570@example.org +cn: user570 +sn: user570 +description: Generated user +uid: user570 +uidNumber: 10570 +gidNumber: 1 +homeDirectory: /home/user570 + +dn: cn=user571,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user571@example.org +cn: user571 +sn: user571 +description: Generated user +uid: user571 +uidNumber: 10571 +gidNumber: 1 +homeDirectory: /home/user571 + +dn: cn=user572,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user572@example.org +cn: user572 +sn: user572 +description: Generated user +uid: user572 +uidNumber: 10572 +gidNumber: 1 +homeDirectory: /home/user572 + +dn: cn=user573,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user573@example.org +cn: user573 +sn: user573 +description: Generated user +uid: user573 +uidNumber: 10573 +gidNumber: 1 +homeDirectory: /home/user573 + +dn: cn=user574,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user574@example.org +cn: user574 +sn: user574 +description: Generated user +uid: user574 +uidNumber: 10574 +gidNumber: 1 +homeDirectory: /home/user574 + +dn: cn=user575,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user575@example.org +cn: user575 +sn: user575 +description: Generated user +uid: user575 +uidNumber: 10575 +gidNumber: 1 +homeDirectory: /home/user575 + +dn: cn=user576,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user576@example.org +cn: user576 +sn: user576 +description: Generated user +uid: user576 +uidNumber: 10576 +gidNumber: 1 +homeDirectory: /home/user576 + +dn: cn=user577,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user577@example.org +cn: user577 +sn: user577 +description: Generated user +uid: user577 +uidNumber: 10577 +gidNumber: 1 +homeDirectory: /home/user577 + +dn: cn=user578,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user578@example.org +cn: user578 +sn: user578 +description: Generated user +uid: user578 +uidNumber: 10578 +gidNumber: 1 +homeDirectory: /home/user578 + +dn: cn=user579,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user579@example.org +cn: user579 +sn: user579 +description: Generated user +uid: user579 +uidNumber: 10579 +gidNumber: 1 +homeDirectory: /home/user579 + +dn: cn=user580,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user580@example.org +cn: user580 +sn: user580 +description: Generated user +uid: user580 +uidNumber: 10580 +gidNumber: 1 +homeDirectory: /home/user580 + +dn: cn=user581,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user581@example.org +cn: user581 +sn: user581 +description: Generated user +uid: user581 +uidNumber: 10581 +gidNumber: 1 +homeDirectory: /home/user581 + +dn: cn=user582,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user582@example.org +cn: user582 +sn: user582 +description: Generated user +uid: user582 +uidNumber: 10582 +gidNumber: 1 +homeDirectory: /home/user582 + +dn: cn=user583,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user583@example.org +cn: user583 +sn: user583 +description: Generated user +uid: user583 +uidNumber: 10583 +gidNumber: 1 +homeDirectory: /home/user583 + +dn: cn=user584,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user584@example.org +cn: user584 +sn: user584 +description: Generated user +uid: user584 +uidNumber: 10584 +gidNumber: 1 +homeDirectory: /home/user584 + +dn: cn=user585,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user585@example.org +cn: user585 +sn: user585 +description: Generated user +uid: user585 +uidNumber: 10585 +gidNumber: 1 +homeDirectory: /home/user585 + +dn: cn=user586,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user586@example.org +cn: user586 +sn: user586 +description: Generated user +uid: user586 +uidNumber: 10586 +gidNumber: 1 +homeDirectory: /home/user586 + +dn: cn=user587,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user587@example.org +cn: user587 +sn: user587 +description: Generated user +uid: user587 +uidNumber: 10587 +gidNumber: 1 +homeDirectory: /home/user587 + +dn: cn=user588,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user588@example.org +cn: user588 +sn: user588 +description: Generated user +uid: user588 +uidNumber: 10588 +gidNumber: 1 +homeDirectory: /home/user588 + +dn: cn=user589,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user589@example.org +cn: user589 +sn: user589 +description: Generated user +uid: user589 +uidNumber: 10589 +gidNumber: 1 +homeDirectory: /home/user589 + +dn: cn=user590,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user590@example.org +cn: user590 +sn: user590 +description: Generated user +uid: user590 +uidNumber: 10590 +gidNumber: 1 +homeDirectory: /home/user590 + +dn: cn=user591,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user591@example.org +cn: user591 +sn: user591 +description: Generated user +uid: user591 +uidNumber: 10591 +gidNumber: 1 +homeDirectory: /home/user591 + +dn: cn=user592,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user592@example.org +cn: user592 +sn: user592 +description: Generated user +uid: user592 +uidNumber: 10592 +gidNumber: 1 +homeDirectory: /home/user592 + +dn: cn=user593,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user593@example.org +cn: user593 +sn: user593 +description: Generated user +uid: user593 +uidNumber: 10593 +gidNumber: 1 +homeDirectory: /home/user593 + +dn: cn=user594,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user594@example.org +cn: user594 +sn: user594 +description: Generated user +uid: user594 +uidNumber: 10594 +gidNumber: 1 +homeDirectory: /home/user594 + +dn: cn=user595,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user595@example.org +cn: user595 +sn: user595 +description: Generated user +uid: user595 +uidNumber: 10595 +gidNumber: 1 +homeDirectory: /home/user595 + +dn: cn=user596,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user596@example.org +cn: user596 +sn: user596 +description: Generated user +uid: user596 +uidNumber: 10596 +gidNumber: 1 +homeDirectory: /home/user596 + +dn: cn=user597,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user597@example.org +cn: user597 +sn: user597 +description: Generated user +uid: user597 +uidNumber: 10597 +gidNumber: 1 +homeDirectory: /home/user597 + +dn: cn=user598,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user598@example.org +cn: user598 +sn: user598 +description: Generated user +uid: user598 +uidNumber: 10598 +gidNumber: 1 +homeDirectory: /home/user598 + +dn: cn=user599,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user599@example.org +cn: user599 +sn: user599 +description: Generated user +uid: user599 +uidNumber: 10599 +gidNumber: 1 +homeDirectory: /home/user599 + +dn: cn=user600,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user600@example.org +cn: user600 +sn: user600 +description: Generated user +uid: user600 +uidNumber: 10600 +gidNumber: 1 +homeDirectory: /home/user600 + +dn: cn=user601,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user601@example.org +cn: user601 +sn: user601 +description: Generated user +uid: user601 +uidNumber: 10601 +gidNumber: 1 +homeDirectory: /home/user601 + +dn: cn=user602,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user602@example.org +cn: user602 +sn: user602 +description: Generated user +uid: user602 +uidNumber: 10602 +gidNumber: 1 +homeDirectory: /home/user602 + +dn: cn=user603,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user603@example.org +cn: user603 +sn: user603 +description: Generated user +uid: user603 +uidNumber: 10603 +gidNumber: 1 +homeDirectory: /home/user603 + +dn: cn=user604,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user604@example.org +cn: user604 +sn: user604 +description: Generated user +uid: user604 +uidNumber: 10604 +gidNumber: 1 +homeDirectory: /home/user604 + +dn: cn=user605,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user605@example.org +cn: user605 +sn: user605 +description: Generated user +uid: user605 +uidNumber: 10605 +gidNumber: 1 +homeDirectory: /home/user605 + +dn: cn=user606,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user606@example.org +cn: user606 +sn: user606 +description: Generated user +uid: user606 +uidNumber: 10606 +gidNumber: 1 +homeDirectory: /home/user606 + +dn: cn=user607,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user607@example.org +cn: user607 +sn: user607 +description: Generated user +uid: user607 +uidNumber: 10607 +gidNumber: 1 +homeDirectory: /home/user607 + +dn: cn=user608,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user608@example.org +cn: user608 +sn: user608 +description: Generated user +uid: user608 +uidNumber: 10608 +gidNumber: 1 +homeDirectory: /home/user608 + +dn: cn=user609,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user609@example.org +cn: user609 +sn: user609 +description: Generated user +uid: user609 +uidNumber: 10609 +gidNumber: 1 +homeDirectory: /home/user609 + +dn: cn=user610,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user610@example.org +cn: user610 +sn: user610 +description: Generated user +uid: user610 +uidNumber: 10610 +gidNumber: 1 +homeDirectory: /home/user610 + +dn: cn=user611,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user611@example.org +cn: user611 +sn: user611 +description: Generated user +uid: user611 +uidNumber: 10611 +gidNumber: 1 +homeDirectory: /home/user611 + +dn: cn=user612,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user612@example.org +cn: user612 +sn: user612 +description: Generated user +uid: user612 +uidNumber: 10612 +gidNumber: 1 +homeDirectory: /home/user612 + +dn: cn=user613,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user613@example.org +cn: user613 +sn: user613 +description: Generated user +uid: user613 +uidNumber: 10613 +gidNumber: 1 +homeDirectory: /home/user613 + +dn: cn=user614,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user614@example.org +cn: user614 +sn: user614 +description: Generated user +uid: user614 +uidNumber: 10614 +gidNumber: 1 +homeDirectory: /home/user614 + +dn: cn=user615,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user615@example.org +cn: user615 +sn: user615 +description: Generated user +uid: user615 +uidNumber: 10615 +gidNumber: 1 +homeDirectory: /home/user615 + +dn: cn=user616,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user616@example.org +cn: user616 +sn: user616 +description: Generated user +uid: user616 +uidNumber: 10616 +gidNumber: 1 +homeDirectory: /home/user616 + +dn: cn=user617,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user617@example.org +cn: user617 +sn: user617 +description: Generated user +uid: user617 +uidNumber: 10617 +gidNumber: 1 +homeDirectory: /home/user617 + +dn: cn=user618,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user618@example.org +cn: user618 +sn: user618 +description: Generated user +uid: user618 +uidNumber: 10618 +gidNumber: 1 +homeDirectory: /home/user618 + +dn: cn=user619,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user619@example.org +cn: user619 +sn: user619 +description: Generated user +uid: user619 +uidNumber: 10619 +gidNumber: 1 +homeDirectory: /home/user619 + +dn: cn=user620,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user620@example.org +cn: user620 +sn: user620 +description: Generated user +uid: user620 +uidNumber: 10620 +gidNumber: 1 +homeDirectory: /home/user620 + +dn: cn=user621,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user621@example.org +cn: user621 +sn: user621 +description: Generated user +uid: user621 +uidNumber: 10621 +gidNumber: 1 +homeDirectory: /home/user621 + +dn: cn=user622,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user622@example.org +cn: user622 +sn: user622 +description: Generated user +uid: user622 +uidNumber: 10622 +gidNumber: 1 +homeDirectory: /home/user622 + +dn: cn=user623,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user623@example.org +cn: user623 +sn: user623 +description: Generated user +uid: user623 +uidNumber: 10623 +gidNumber: 1 +homeDirectory: /home/user623 + +dn: cn=user624,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user624@example.org +cn: user624 +sn: user624 +description: Generated user +uid: user624 +uidNumber: 10624 +gidNumber: 1 +homeDirectory: /home/user624 + +dn: cn=user625,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user625@example.org +cn: user625 +sn: user625 +description: Generated user +uid: user625 +uidNumber: 10625 +gidNumber: 1 +homeDirectory: /home/user625 + +dn: cn=user626,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user626@example.org +cn: user626 +sn: user626 +description: Generated user +uid: user626 +uidNumber: 10626 +gidNumber: 1 +homeDirectory: /home/user626 + +dn: cn=user627,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user627@example.org +cn: user627 +sn: user627 +description: Generated user +uid: user627 +uidNumber: 10627 +gidNumber: 1 +homeDirectory: /home/user627 + +dn: cn=user628,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user628@example.org +cn: user628 +sn: user628 +description: Generated user +uid: user628 +uidNumber: 10628 +gidNumber: 1 +homeDirectory: /home/user628 + +dn: cn=user629,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user629@example.org +cn: user629 +sn: user629 +description: Generated user +uid: user629 +uidNumber: 10629 +gidNumber: 1 +homeDirectory: /home/user629 + +dn: cn=user630,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user630@example.org +cn: user630 +sn: user630 +description: Generated user +uid: user630 +uidNumber: 10630 +gidNumber: 1 +homeDirectory: /home/user630 + +dn: cn=user631,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user631@example.org +cn: user631 +sn: user631 +description: Generated user +uid: user631 +uidNumber: 10631 +gidNumber: 1 +homeDirectory: /home/user631 + +dn: cn=user632,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user632@example.org +cn: user632 +sn: user632 +description: Generated user +uid: user632 +uidNumber: 10632 +gidNumber: 1 +homeDirectory: /home/user632 + +dn: cn=user633,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user633@example.org +cn: user633 +sn: user633 +description: Generated user +uid: user633 +uidNumber: 10633 +gidNumber: 1 +homeDirectory: /home/user633 + +dn: cn=user634,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user634@example.org +cn: user634 +sn: user634 +description: Generated user +uid: user634 +uidNumber: 10634 +gidNumber: 1 +homeDirectory: /home/user634 + +dn: cn=user635,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user635@example.org +cn: user635 +sn: user635 +description: Generated user +uid: user635 +uidNumber: 10635 +gidNumber: 1 +homeDirectory: /home/user635 + +dn: cn=user636,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user636@example.org +cn: user636 +sn: user636 +description: Generated user +uid: user636 +uidNumber: 10636 +gidNumber: 1 +homeDirectory: /home/user636 + +dn: cn=user637,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user637@example.org +cn: user637 +sn: user637 +description: Generated user +uid: user637 +uidNumber: 10637 +gidNumber: 1 +homeDirectory: /home/user637 + +dn: cn=user638,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user638@example.org +cn: user638 +sn: user638 +description: Generated user +uid: user638 +uidNumber: 10638 +gidNumber: 1 +homeDirectory: /home/user638 + +dn: cn=user639,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user639@example.org +cn: user639 +sn: user639 +description: Generated user +uid: user639 +uidNumber: 10639 +gidNumber: 1 +homeDirectory: /home/user639 + +dn: cn=user640,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user640@example.org +cn: user640 +sn: user640 +description: Generated user +uid: user640 +uidNumber: 10640 +gidNumber: 1 +homeDirectory: /home/user640 + +dn: cn=user641,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user641@example.org +cn: user641 +sn: user641 +description: Generated user +uid: user641 +uidNumber: 10641 +gidNumber: 1 +homeDirectory: /home/user641 + +dn: cn=user642,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user642@example.org +cn: user642 +sn: user642 +description: Generated user +uid: user642 +uidNumber: 10642 +gidNumber: 1 +homeDirectory: /home/user642 + +dn: cn=user643,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user643@example.org +cn: user643 +sn: user643 +description: Generated user +uid: user643 +uidNumber: 10643 +gidNumber: 1 +homeDirectory: /home/user643 + +dn: cn=user644,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user644@example.org +cn: user644 +sn: user644 +description: Generated user +uid: user644 +uidNumber: 10644 +gidNumber: 1 +homeDirectory: /home/user644 + +dn: cn=user645,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user645@example.org +cn: user645 +sn: user645 +description: Generated user +uid: user645 +uidNumber: 10645 +gidNumber: 1 +homeDirectory: /home/user645 + +dn: cn=user646,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user646@example.org +cn: user646 +sn: user646 +description: Generated user +uid: user646 +uidNumber: 10646 +gidNumber: 1 +homeDirectory: /home/user646 + +dn: cn=user647,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user647@example.org +cn: user647 +sn: user647 +description: Generated user +uid: user647 +uidNumber: 10647 +gidNumber: 1 +homeDirectory: /home/user647 + +dn: cn=user648,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user648@example.org +cn: user648 +sn: user648 +description: Generated user +uid: user648 +uidNumber: 10648 +gidNumber: 1 +homeDirectory: /home/user648 + +dn: cn=user649,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user649@example.org +cn: user649 +sn: user649 +description: Generated user +uid: user649 +uidNumber: 10649 +gidNumber: 1 +homeDirectory: /home/user649 + +dn: cn=user650,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user650@example.org +cn: user650 +sn: user650 +description: Generated user +uid: user650 +uidNumber: 10650 +gidNumber: 1 +homeDirectory: /home/user650 + +dn: cn=user651,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user651@example.org +cn: user651 +sn: user651 +description: Generated user +uid: user651 +uidNumber: 10651 +gidNumber: 1 +homeDirectory: /home/user651 + +dn: cn=user652,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user652@example.org +cn: user652 +sn: user652 +description: Generated user +uid: user652 +uidNumber: 10652 +gidNumber: 1 +homeDirectory: /home/user652 + +dn: cn=user653,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user653@example.org +cn: user653 +sn: user653 +description: Generated user +uid: user653 +uidNumber: 10653 +gidNumber: 1 +homeDirectory: /home/user653 + +dn: cn=user654,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user654@example.org +cn: user654 +sn: user654 +description: Generated user +uid: user654 +uidNumber: 10654 +gidNumber: 1 +homeDirectory: /home/user654 + +dn: cn=user655,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user655@example.org +cn: user655 +sn: user655 +description: Generated user +uid: user655 +uidNumber: 10655 +gidNumber: 1 +homeDirectory: /home/user655 + +dn: cn=user656,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user656@example.org +cn: user656 +sn: user656 +description: Generated user +uid: user656 +uidNumber: 10656 +gidNumber: 1 +homeDirectory: /home/user656 + +dn: cn=user657,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user657@example.org +cn: user657 +sn: user657 +description: Generated user +uid: user657 +uidNumber: 10657 +gidNumber: 1 +homeDirectory: /home/user657 + +dn: cn=user658,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user658@example.org +cn: user658 +sn: user658 +description: Generated user +uid: user658 +uidNumber: 10658 +gidNumber: 1 +homeDirectory: /home/user658 + +dn: cn=user659,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user659@example.org +cn: user659 +sn: user659 +description: Generated user +uid: user659 +uidNumber: 10659 +gidNumber: 1 +homeDirectory: /home/user659 + +dn: cn=user660,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user660@example.org +cn: user660 +sn: user660 +description: Generated user +uid: user660 +uidNumber: 10660 +gidNumber: 1 +homeDirectory: /home/user660 + +dn: cn=user661,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user661@example.org +cn: user661 +sn: user661 +description: Generated user +uid: user661 +uidNumber: 10661 +gidNumber: 1 +homeDirectory: /home/user661 + +dn: cn=user662,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user662@example.org +cn: user662 +sn: user662 +description: Generated user +uid: user662 +uidNumber: 10662 +gidNumber: 1 +homeDirectory: /home/user662 + +dn: cn=user663,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user663@example.org +cn: user663 +sn: user663 +description: Generated user +uid: user663 +uidNumber: 10663 +gidNumber: 1 +homeDirectory: /home/user663 + +dn: cn=user664,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user664@example.org +cn: user664 +sn: user664 +description: Generated user +uid: user664 +uidNumber: 10664 +gidNumber: 1 +homeDirectory: /home/user664 + +dn: cn=user665,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user665@example.org +cn: user665 +sn: user665 +description: Generated user +uid: user665 +uidNumber: 10665 +gidNumber: 1 +homeDirectory: /home/user665 + +dn: cn=user666,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user666@example.org +cn: user666 +sn: user666 +description: Generated user +uid: user666 +uidNumber: 10666 +gidNumber: 1 +homeDirectory: /home/user666 + +dn: cn=user667,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user667@example.org +cn: user667 +sn: user667 +description: Generated user +uid: user667 +uidNumber: 10667 +gidNumber: 1 +homeDirectory: /home/user667 + +dn: cn=user668,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user668@example.org +cn: user668 +sn: user668 +description: Generated user +uid: user668 +uidNumber: 10668 +gidNumber: 1 +homeDirectory: /home/user668 + +dn: cn=user669,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user669@example.org +cn: user669 +sn: user669 +description: Generated user +uid: user669 +uidNumber: 10669 +gidNumber: 1 +homeDirectory: /home/user669 + +dn: cn=user670,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user670@example.org +cn: user670 +sn: user670 +description: Generated user +uid: user670 +uidNumber: 10670 +gidNumber: 1 +homeDirectory: /home/user670 + +dn: cn=user671,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user671@example.org +cn: user671 +sn: user671 +description: Generated user +uid: user671 +uidNumber: 10671 +gidNumber: 1 +homeDirectory: /home/user671 + +dn: cn=user672,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user672@example.org +cn: user672 +sn: user672 +description: Generated user +uid: user672 +uidNumber: 10672 +gidNumber: 1 +homeDirectory: /home/user672 + +dn: cn=user673,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user673@example.org +cn: user673 +sn: user673 +description: Generated user +uid: user673 +uidNumber: 10673 +gidNumber: 1 +homeDirectory: /home/user673 + +dn: cn=user674,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user674@example.org +cn: user674 +sn: user674 +description: Generated user +uid: user674 +uidNumber: 10674 +gidNumber: 1 +homeDirectory: /home/user674 + +dn: cn=user675,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user675@example.org +cn: user675 +sn: user675 +description: Generated user +uid: user675 +uidNumber: 10675 +gidNumber: 1 +homeDirectory: /home/user675 + +dn: cn=user676,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user676@example.org +cn: user676 +sn: user676 +description: Generated user +uid: user676 +uidNumber: 10676 +gidNumber: 1 +homeDirectory: /home/user676 + +dn: cn=user677,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user677@example.org +cn: user677 +sn: user677 +description: Generated user +uid: user677 +uidNumber: 10677 +gidNumber: 1 +homeDirectory: /home/user677 + +dn: cn=user678,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user678@example.org +cn: user678 +sn: user678 +description: Generated user +uid: user678 +uidNumber: 10678 +gidNumber: 1 +homeDirectory: /home/user678 + +dn: cn=user679,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user679@example.org +cn: user679 +sn: user679 +description: Generated user +uid: user679 +uidNumber: 10679 +gidNumber: 1 +homeDirectory: /home/user679 + +dn: cn=user680,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user680@example.org +cn: user680 +sn: user680 +description: Generated user +uid: user680 +uidNumber: 10680 +gidNumber: 1 +homeDirectory: /home/user680 + +dn: cn=user681,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user681@example.org +cn: user681 +sn: user681 +description: Generated user +uid: user681 +uidNumber: 10681 +gidNumber: 1 +homeDirectory: /home/user681 + +dn: cn=user682,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user682@example.org +cn: user682 +sn: user682 +description: Generated user +uid: user682 +uidNumber: 10682 +gidNumber: 1 +homeDirectory: /home/user682 + +dn: cn=user683,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user683@example.org +cn: user683 +sn: user683 +description: Generated user +uid: user683 +uidNumber: 10683 +gidNumber: 1 +homeDirectory: /home/user683 + +dn: cn=user684,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user684@example.org +cn: user684 +sn: user684 +description: Generated user +uid: user684 +uidNumber: 10684 +gidNumber: 1 +homeDirectory: /home/user684 + +dn: cn=user685,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user685@example.org +cn: user685 +sn: user685 +description: Generated user +uid: user685 +uidNumber: 10685 +gidNumber: 1 +homeDirectory: /home/user685 + +dn: cn=user686,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user686@example.org +cn: user686 +sn: user686 +description: Generated user +uid: user686 +uidNumber: 10686 +gidNumber: 1 +homeDirectory: /home/user686 + +dn: cn=user687,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user687@example.org +cn: user687 +sn: user687 +description: Generated user +uid: user687 +uidNumber: 10687 +gidNumber: 1 +homeDirectory: /home/user687 + +dn: cn=user688,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user688@example.org +cn: user688 +sn: user688 +description: Generated user +uid: user688 +uidNumber: 10688 +gidNumber: 1 +homeDirectory: /home/user688 + +dn: cn=user689,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user689@example.org +cn: user689 +sn: user689 +description: Generated user +uid: user689 +uidNumber: 10689 +gidNumber: 1 +homeDirectory: /home/user689 + +dn: cn=user690,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user690@example.org +cn: user690 +sn: user690 +description: Generated user +uid: user690 +uidNumber: 10690 +gidNumber: 1 +homeDirectory: /home/user690 + +dn: cn=user691,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user691@example.org +cn: user691 +sn: user691 +description: Generated user +uid: user691 +uidNumber: 10691 +gidNumber: 1 +homeDirectory: /home/user691 + +dn: cn=user692,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user692@example.org +cn: user692 +sn: user692 +description: Generated user +uid: user692 +uidNumber: 10692 +gidNumber: 1 +homeDirectory: /home/user692 + +dn: cn=user693,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user693@example.org +cn: user693 +sn: user693 +description: Generated user +uid: user693 +uidNumber: 10693 +gidNumber: 1 +homeDirectory: /home/user693 + +dn: cn=user694,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user694@example.org +cn: user694 +sn: user694 +description: Generated user +uid: user694 +uidNumber: 10694 +gidNumber: 1 +homeDirectory: /home/user694 + +dn: cn=user695,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user695@example.org +cn: user695 +sn: user695 +description: Generated user +uid: user695 +uidNumber: 10695 +gidNumber: 1 +homeDirectory: /home/user695 + +dn: cn=user696,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user696@example.org +cn: user696 +sn: user696 +description: Generated user +uid: user696 +uidNumber: 10696 +gidNumber: 1 +homeDirectory: /home/user696 + +dn: cn=user697,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user697@example.org +cn: user697 +sn: user697 +description: Generated user +uid: user697 +uidNumber: 10697 +gidNumber: 1 +homeDirectory: /home/user697 + +dn: cn=user698,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user698@example.org +cn: user698 +sn: user698 +description: Generated user +uid: user698 +uidNumber: 10698 +gidNumber: 1 +homeDirectory: /home/user698 + +dn: cn=user699,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user699@example.org +cn: user699 +sn: user699 +description: Generated user +uid: user699 +uidNumber: 10699 +gidNumber: 1 +homeDirectory: /home/user699 + +dn: cn=user700,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user700@example.org +cn: user700 +sn: user700 +description: Generated user +uid: user700 +uidNumber: 10700 +gidNumber: 1 +homeDirectory: /home/user700 + +dn: cn=user701,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user701@example.org +cn: user701 +sn: user701 +description: Generated user +uid: user701 +uidNumber: 10701 +gidNumber: 1 +homeDirectory: /home/user701 + +dn: cn=user702,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user702@example.org +cn: user702 +sn: user702 +description: Generated user +uid: user702 +uidNumber: 10702 +gidNumber: 1 +homeDirectory: /home/user702 + +dn: cn=user703,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user703@example.org +cn: user703 +sn: user703 +description: Generated user +uid: user703 +uidNumber: 10703 +gidNumber: 1 +homeDirectory: /home/user703 + +dn: cn=user704,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user704@example.org +cn: user704 +sn: user704 +description: Generated user +uid: user704 +uidNumber: 10704 +gidNumber: 1 +homeDirectory: /home/user704 + +dn: cn=user705,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user705@example.org +cn: user705 +sn: user705 +description: Generated user +uid: user705 +uidNumber: 10705 +gidNumber: 1 +homeDirectory: /home/user705 + +dn: cn=user706,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user706@example.org +cn: user706 +sn: user706 +description: Generated user +uid: user706 +uidNumber: 10706 +gidNumber: 1 +homeDirectory: /home/user706 + +dn: cn=user707,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user707@example.org +cn: user707 +sn: user707 +description: Generated user +uid: user707 +uidNumber: 10707 +gidNumber: 1 +homeDirectory: /home/user707 + +dn: cn=user708,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user708@example.org +cn: user708 +sn: user708 +description: Generated user +uid: user708 +uidNumber: 10708 +gidNumber: 1 +homeDirectory: /home/user708 + +dn: cn=user709,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user709@example.org +cn: user709 +sn: user709 +description: Generated user +uid: user709 +uidNumber: 10709 +gidNumber: 1 +homeDirectory: /home/user709 + +dn: cn=user710,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user710@example.org +cn: user710 +sn: user710 +description: Generated user +uid: user710 +uidNumber: 10710 +gidNumber: 1 +homeDirectory: /home/user710 + +dn: cn=user711,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user711@example.org +cn: user711 +sn: user711 +description: Generated user +uid: user711 +uidNumber: 10711 +gidNumber: 1 +homeDirectory: /home/user711 + +dn: cn=user712,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user712@example.org +cn: user712 +sn: user712 +description: Generated user +uid: user712 +uidNumber: 10712 +gidNumber: 1 +homeDirectory: /home/user712 + +dn: cn=user713,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user713@example.org +cn: user713 +sn: user713 +description: Generated user +uid: user713 +uidNumber: 10713 +gidNumber: 1 +homeDirectory: /home/user713 + +dn: cn=user714,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user714@example.org +cn: user714 +sn: user714 +description: Generated user +uid: user714 +uidNumber: 10714 +gidNumber: 1 +homeDirectory: /home/user714 + +dn: cn=user715,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user715@example.org +cn: user715 +sn: user715 +description: Generated user +uid: user715 +uidNumber: 10715 +gidNumber: 1 +homeDirectory: /home/user715 + +dn: cn=user716,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user716@example.org +cn: user716 +sn: user716 +description: Generated user +uid: user716 +uidNumber: 10716 +gidNumber: 1 +homeDirectory: /home/user716 + +dn: cn=user717,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user717@example.org +cn: user717 +sn: user717 +description: Generated user +uid: user717 +uidNumber: 10717 +gidNumber: 1 +homeDirectory: /home/user717 + +dn: cn=user718,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user718@example.org +cn: user718 +sn: user718 +description: Generated user +uid: user718 +uidNumber: 10718 +gidNumber: 1 +homeDirectory: /home/user718 + +dn: cn=user719,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user719@example.org +cn: user719 +sn: user719 +description: Generated user +uid: user719 +uidNumber: 10719 +gidNumber: 1 +homeDirectory: /home/user719 + +dn: cn=user720,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user720@example.org +cn: user720 +sn: user720 +description: Generated user +uid: user720 +uidNumber: 10720 +gidNumber: 1 +homeDirectory: /home/user720 + +dn: cn=user721,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user721@example.org +cn: user721 +sn: user721 +description: Generated user +uid: user721 +uidNumber: 10721 +gidNumber: 1 +homeDirectory: /home/user721 + +dn: cn=user722,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user722@example.org +cn: user722 +sn: user722 +description: Generated user +uid: user722 +uidNumber: 10722 +gidNumber: 1 +homeDirectory: /home/user722 + +dn: cn=user723,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user723@example.org +cn: user723 +sn: user723 +description: Generated user +uid: user723 +uidNumber: 10723 +gidNumber: 1 +homeDirectory: /home/user723 + +dn: cn=user724,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user724@example.org +cn: user724 +sn: user724 +description: Generated user +uid: user724 +uidNumber: 10724 +gidNumber: 1 +homeDirectory: /home/user724 + +dn: cn=user725,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user725@example.org +cn: user725 +sn: user725 +description: Generated user +uid: user725 +uidNumber: 10725 +gidNumber: 1 +homeDirectory: /home/user725 + +dn: cn=user726,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user726@example.org +cn: user726 +sn: user726 +description: Generated user +uid: user726 +uidNumber: 10726 +gidNumber: 1 +homeDirectory: /home/user726 + +dn: cn=user727,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user727@example.org +cn: user727 +sn: user727 +description: Generated user +uid: user727 +uidNumber: 10727 +gidNumber: 1 +homeDirectory: /home/user727 + +dn: cn=user728,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user728@example.org +cn: user728 +sn: user728 +description: Generated user +uid: user728 +uidNumber: 10728 +gidNumber: 1 +homeDirectory: /home/user728 + +dn: cn=user729,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user729@example.org +cn: user729 +sn: user729 +description: Generated user +uid: user729 +uidNumber: 10729 +gidNumber: 1 +homeDirectory: /home/user729 + +dn: cn=user730,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user730@example.org +cn: user730 +sn: user730 +description: Generated user +uid: user730 +uidNumber: 10730 +gidNumber: 1 +homeDirectory: /home/user730 + +dn: cn=user731,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user731@example.org +cn: user731 +sn: user731 +description: Generated user +uid: user731 +uidNumber: 10731 +gidNumber: 1 +homeDirectory: /home/user731 + +dn: cn=user732,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user732@example.org +cn: user732 +sn: user732 +description: Generated user +uid: user732 +uidNumber: 10732 +gidNumber: 1 +homeDirectory: /home/user732 + +dn: cn=user733,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user733@example.org +cn: user733 +sn: user733 +description: Generated user +uid: user733 +uidNumber: 10733 +gidNumber: 1 +homeDirectory: /home/user733 + +dn: cn=user734,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user734@example.org +cn: user734 +sn: user734 +description: Generated user +uid: user734 +uidNumber: 10734 +gidNumber: 1 +homeDirectory: /home/user734 + +dn: cn=user735,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user735@example.org +cn: user735 +sn: user735 +description: Generated user +uid: user735 +uidNumber: 10735 +gidNumber: 1 +homeDirectory: /home/user735 + +dn: cn=user736,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user736@example.org +cn: user736 +sn: user736 +description: Generated user +uid: user736 +uidNumber: 10736 +gidNumber: 1 +homeDirectory: /home/user736 + +dn: cn=user737,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user737@example.org +cn: user737 +sn: user737 +description: Generated user +uid: user737 +uidNumber: 10737 +gidNumber: 1 +homeDirectory: /home/user737 + +dn: cn=user738,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user738@example.org +cn: user738 +sn: user738 +description: Generated user +uid: user738 +uidNumber: 10738 +gidNumber: 1 +homeDirectory: /home/user738 + +dn: cn=user739,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user739@example.org +cn: user739 +sn: user739 +description: Generated user +uid: user739 +uidNumber: 10739 +gidNumber: 1 +homeDirectory: /home/user739 + +dn: cn=user740,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user740@example.org +cn: user740 +sn: user740 +description: Generated user +uid: user740 +uidNumber: 10740 +gidNumber: 1 +homeDirectory: /home/user740 + +dn: cn=user741,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user741@example.org +cn: user741 +sn: user741 +description: Generated user +uid: user741 +uidNumber: 10741 +gidNumber: 1 +homeDirectory: /home/user741 + +dn: cn=user742,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user742@example.org +cn: user742 +sn: user742 +description: Generated user +uid: user742 +uidNumber: 10742 +gidNumber: 1 +homeDirectory: /home/user742 + +dn: cn=user743,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user743@example.org +cn: user743 +sn: user743 +description: Generated user +uid: user743 +uidNumber: 10743 +gidNumber: 1 +homeDirectory: /home/user743 + +dn: cn=user744,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user744@example.org +cn: user744 +sn: user744 +description: Generated user +uid: user744 +uidNumber: 10744 +gidNumber: 1 +homeDirectory: /home/user744 + +dn: cn=user745,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user745@example.org +cn: user745 +sn: user745 +description: Generated user +uid: user745 +uidNumber: 10745 +gidNumber: 1 +homeDirectory: /home/user745 + +dn: cn=user746,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user746@example.org +cn: user746 +sn: user746 +description: Generated user +uid: user746 +uidNumber: 10746 +gidNumber: 1 +homeDirectory: /home/user746 + +dn: cn=user747,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user747@example.org +cn: user747 +sn: user747 +description: Generated user +uid: user747 +uidNumber: 10747 +gidNumber: 1 +homeDirectory: /home/user747 + +dn: cn=user748,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user748@example.org +cn: user748 +sn: user748 +description: Generated user +uid: user748 +uidNumber: 10748 +gidNumber: 1 +homeDirectory: /home/user748 + +dn: cn=user749,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user749@example.org +cn: user749 +sn: user749 +description: Generated user +uid: user749 +uidNumber: 10749 +gidNumber: 1 +homeDirectory: /home/user749 + +dn: cn=user750,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user750@example.org +cn: user750 +sn: user750 +description: Generated user +uid: user750 +uidNumber: 10750 +gidNumber: 1 +homeDirectory: /home/user750 + +dn: cn=user751,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user751@example.org +cn: user751 +sn: user751 +description: Generated user +uid: user751 +uidNumber: 10751 +gidNumber: 1 +homeDirectory: /home/user751 + +dn: cn=user752,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user752@example.org +cn: user752 +sn: user752 +description: Generated user +uid: user752 +uidNumber: 10752 +gidNumber: 1 +homeDirectory: /home/user752 + +dn: cn=user753,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user753@example.org +cn: user753 +sn: user753 +description: Generated user +uid: user753 +uidNumber: 10753 +gidNumber: 1 +homeDirectory: /home/user753 + +dn: cn=user754,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user754@example.org +cn: user754 +sn: user754 +description: Generated user +uid: user754 +uidNumber: 10754 +gidNumber: 1 +homeDirectory: /home/user754 + +dn: cn=user755,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user755@example.org +cn: user755 +sn: user755 +description: Generated user +uid: user755 +uidNumber: 10755 +gidNumber: 1 +homeDirectory: /home/user755 + +dn: cn=user756,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user756@example.org +cn: user756 +sn: user756 +description: Generated user +uid: user756 +uidNumber: 10756 +gidNumber: 1 +homeDirectory: /home/user756 + +dn: cn=user757,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user757@example.org +cn: user757 +sn: user757 +description: Generated user +uid: user757 +uidNumber: 10757 +gidNumber: 1 +homeDirectory: /home/user757 + +dn: cn=user758,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user758@example.org +cn: user758 +sn: user758 +description: Generated user +uid: user758 +uidNumber: 10758 +gidNumber: 1 +homeDirectory: /home/user758 + +dn: cn=user759,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user759@example.org +cn: user759 +sn: user759 +description: Generated user +uid: user759 +uidNumber: 10759 +gidNumber: 1 +homeDirectory: /home/user759 + +dn: cn=user760,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user760@example.org +cn: user760 +sn: user760 +description: Generated user +uid: user760 +uidNumber: 10760 +gidNumber: 1 +homeDirectory: /home/user760 + +dn: cn=user761,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user761@example.org +cn: user761 +sn: user761 +description: Generated user +uid: user761 +uidNumber: 10761 +gidNumber: 1 +homeDirectory: /home/user761 + +dn: cn=user762,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user762@example.org +cn: user762 +sn: user762 +description: Generated user +uid: user762 +uidNumber: 10762 +gidNumber: 1 +homeDirectory: /home/user762 + +dn: cn=user763,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user763@example.org +cn: user763 +sn: user763 +description: Generated user +uid: user763 +uidNumber: 10763 +gidNumber: 1 +homeDirectory: /home/user763 + +dn: cn=user764,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user764@example.org +cn: user764 +sn: user764 +description: Generated user +uid: user764 +uidNumber: 10764 +gidNumber: 1 +homeDirectory: /home/user764 + +dn: cn=user765,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user765@example.org +cn: user765 +sn: user765 +description: Generated user +uid: user765 +uidNumber: 10765 +gidNumber: 1 +homeDirectory: /home/user765 + +dn: cn=user766,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user766@example.org +cn: user766 +sn: user766 +description: Generated user +uid: user766 +uidNumber: 10766 +gidNumber: 1 +homeDirectory: /home/user766 + +dn: cn=user767,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user767@example.org +cn: user767 +sn: user767 +description: Generated user +uid: user767 +uidNumber: 10767 +gidNumber: 1 +homeDirectory: /home/user767 + +dn: cn=user768,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user768@example.org +cn: user768 +sn: user768 +description: Generated user +uid: user768 +uidNumber: 10768 +gidNumber: 1 +homeDirectory: /home/user768 + +dn: cn=user769,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user769@example.org +cn: user769 +sn: user769 +description: Generated user +uid: user769 +uidNumber: 10769 +gidNumber: 1 +homeDirectory: /home/user769 + +dn: cn=user770,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user770@example.org +cn: user770 +sn: user770 +description: Generated user +uid: user770 +uidNumber: 10770 +gidNumber: 1 +homeDirectory: /home/user770 + +dn: cn=user771,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user771@example.org +cn: user771 +sn: user771 +description: Generated user +uid: user771 +uidNumber: 10771 +gidNumber: 1 +homeDirectory: /home/user771 + +dn: cn=user772,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user772@example.org +cn: user772 +sn: user772 +description: Generated user +uid: user772 +uidNumber: 10772 +gidNumber: 1 +homeDirectory: /home/user772 + +dn: cn=user773,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user773@example.org +cn: user773 +sn: user773 +description: Generated user +uid: user773 +uidNumber: 10773 +gidNumber: 1 +homeDirectory: /home/user773 + +dn: cn=user774,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user774@example.org +cn: user774 +sn: user774 +description: Generated user +uid: user774 +uidNumber: 10774 +gidNumber: 1 +homeDirectory: /home/user774 + +dn: cn=user775,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user775@example.org +cn: user775 +sn: user775 +description: Generated user +uid: user775 +uidNumber: 10775 +gidNumber: 1 +homeDirectory: /home/user775 + +dn: cn=user776,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user776@example.org +cn: user776 +sn: user776 +description: Generated user +uid: user776 +uidNumber: 10776 +gidNumber: 1 +homeDirectory: /home/user776 + +dn: cn=user777,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user777@example.org +cn: user777 +sn: user777 +description: Generated user +uid: user777 +uidNumber: 10777 +gidNumber: 1 +homeDirectory: /home/user777 + +dn: cn=user778,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user778@example.org +cn: user778 +sn: user778 +description: Generated user +uid: user778 +uidNumber: 10778 +gidNumber: 1 +homeDirectory: /home/user778 + +dn: cn=user779,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user779@example.org +cn: user779 +sn: user779 +description: Generated user +uid: user779 +uidNumber: 10779 +gidNumber: 1 +homeDirectory: /home/user779 + +dn: cn=user780,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user780@example.org +cn: user780 +sn: user780 +description: Generated user +uid: user780 +uidNumber: 10780 +gidNumber: 1 +homeDirectory: /home/user780 + +dn: cn=user781,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user781@example.org +cn: user781 +sn: user781 +description: Generated user +uid: user781 +uidNumber: 10781 +gidNumber: 1 +homeDirectory: /home/user781 + +dn: cn=user782,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user782@example.org +cn: user782 +sn: user782 +description: Generated user +uid: user782 +uidNumber: 10782 +gidNumber: 1 +homeDirectory: /home/user782 + +dn: cn=user783,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user783@example.org +cn: user783 +sn: user783 +description: Generated user +uid: user783 +uidNumber: 10783 +gidNumber: 1 +homeDirectory: /home/user783 + +dn: cn=user784,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user784@example.org +cn: user784 +sn: user784 +description: Generated user +uid: user784 +uidNumber: 10784 +gidNumber: 1 +homeDirectory: /home/user784 + +dn: cn=user785,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user785@example.org +cn: user785 +sn: user785 +description: Generated user +uid: user785 +uidNumber: 10785 +gidNumber: 1 +homeDirectory: /home/user785 + +dn: cn=user786,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user786@example.org +cn: user786 +sn: user786 +description: Generated user +uid: user786 +uidNumber: 10786 +gidNumber: 1 +homeDirectory: /home/user786 + +dn: cn=user787,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user787@example.org +cn: user787 +sn: user787 +description: Generated user +uid: user787 +uidNumber: 10787 +gidNumber: 1 +homeDirectory: /home/user787 + +dn: cn=user788,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user788@example.org +cn: user788 +sn: user788 +description: Generated user +uid: user788 +uidNumber: 10788 +gidNumber: 1 +homeDirectory: /home/user788 + +dn: cn=user789,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user789@example.org +cn: user789 +sn: user789 +description: Generated user +uid: user789 +uidNumber: 10789 +gidNumber: 1 +homeDirectory: /home/user789 + +dn: cn=user790,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user790@example.org +cn: user790 +sn: user790 +description: Generated user +uid: user790 +uidNumber: 10790 +gidNumber: 1 +homeDirectory: /home/user790 + +dn: cn=user791,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user791@example.org +cn: user791 +sn: user791 +description: Generated user +uid: user791 +uidNumber: 10791 +gidNumber: 1 +homeDirectory: /home/user791 + +dn: cn=user792,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user792@example.org +cn: user792 +sn: user792 +description: Generated user +uid: user792 +uidNumber: 10792 +gidNumber: 1 +homeDirectory: /home/user792 + +dn: cn=user793,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user793@example.org +cn: user793 +sn: user793 +description: Generated user +uid: user793 +uidNumber: 10793 +gidNumber: 1 +homeDirectory: /home/user793 + +dn: cn=user794,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user794@example.org +cn: user794 +sn: user794 +description: Generated user +uid: user794 +uidNumber: 10794 +gidNumber: 1 +homeDirectory: /home/user794 + +dn: cn=user795,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user795@example.org +cn: user795 +sn: user795 +description: Generated user +uid: user795 +uidNumber: 10795 +gidNumber: 1 +homeDirectory: /home/user795 + +dn: cn=user796,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user796@example.org +cn: user796 +sn: user796 +description: Generated user +uid: user796 +uidNumber: 10796 +gidNumber: 1 +homeDirectory: /home/user796 + +dn: cn=user797,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user797@example.org +cn: user797 +sn: user797 +description: Generated user +uid: user797 +uidNumber: 10797 +gidNumber: 1 +homeDirectory: /home/user797 + +dn: cn=user798,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user798@example.org +cn: user798 +sn: user798 +description: Generated user +uid: user798 +uidNumber: 10798 +gidNumber: 1 +homeDirectory: /home/user798 + +dn: cn=user799,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user799@example.org +cn: user799 +sn: user799 +description: Generated user +uid: user799 +uidNumber: 10799 +gidNumber: 1 +homeDirectory: /home/user799 + +dn: cn=user800,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user800@example.org +cn: user800 +sn: user800 +description: Generated user +uid: user800 +uidNumber: 10800 +gidNumber: 1 +homeDirectory: /home/user800 + +dn: cn=user801,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user801@example.org +cn: user801 +sn: user801 +description: Generated user +uid: user801 +uidNumber: 10801 +gidNumber: 1 +homeDirectory: /home/user801 + +dn: cn=user802,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user802@example.org +cn: user802 +sn: user802 +description: Generated user +uid: user802 +uidNumber: 10802 +gidNumber: 1 +homeDirectory: /home/user802 + +dn: cn=user803,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user803@example.org +cn: user803 +sn: user803 +description: Generated user +uid: user803 +uidNumber: 10803 +gidNumber: 1 +homeDirectory: /home/user803 + +dn: cn=user804,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user804@example.org +cn: user804 +sn: user804 +description: Generated user +uid: user804 +uidNumber: 10804 +gidNumber: 1 +homeDirectory: /home/user804 + +dn: cn=user805,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user805@example.org +cn: user805 +sn: user805 +description: Generated user +uid: user805 +uidNumber: 10805 +gidNumber: 1 +homeDirectory: /home/user805 + +dn: cn=user806,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user806@example.org +cn: user806 +sn: user806 +description: Generated user +uid: user806 +uidNumber: 10806 +gidNumber: 1 +homeDirectory: /home/user806 + +dn: cn=user807,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user807@example.org +cn: user807 +sn: user807 +description: Generated user +uid: user807 +uidNumber: 10807 +gidNumber: 1 +homeDirectory: /home/user807 + +dn: cn=user808,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user808@example.org +cn: user808 +sn: user808 +description: Generated user +uid: user808 +uidNumber: 10808 +gidNumber: 1 +homeDirectory: /home/user808 + +dn: cn=user809,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user809@example.org +cn: user809 +sn: user809 +description: Generated user +uid: user809 +uidNumber: 10809 +gidNumber: 1 +homeDirectory: /home/user809 + +dn: cn=user810,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user810@example.org +cn: user810 +sn: user810 +description: Generated user +uid: user810 +uidNumber: 10810 +gidNumber: 1 +homeDirectory: /home/user810 + +dn: cn=user811,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user811@example.org +cn: user811 +sn: user811 +description: Generated user +uid: user811 +uidNumber: 10811 +gidNumber: 1 +homeDirectory: /home/user811 + +dn: cn=user812,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user812@example.org +cn: user812 +sn: user812 +description: Generated user +uid: user812 +uidNumber: 10812 +gidNumber: 1 +homeDirectory: /home/user812 + +dn: cn=user813,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user813@example.org +cn: user813 +sn: user813 +description: Generated user +uid: user813 +uidNumber: 10813 +gidNumber: 1 +homeDirectory: /home/user813 + +dn: cn=user814,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user814@example.org +cn: user814 +sn: user814 +description: Generated user +uid: user814 +uidNumber: 10814 +gidNumber: 1 +homeDirectory: /home/user814 + +dn: cn=user815,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user815@example.org +cn: user815 +sn: user815 +description: Generated user +uid: user815 +uidNumber: 10815 +gidNumber: 1 +homeDirectory: /home/user815 + +dn: cn=user816,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user816@example.org +cn: user816 +sn: user816 +description: Generated user +uid: user816 +uidNumber: 10816 +gidNumber: 1 +homeDirectory: /home/user816 + +dn: cn=user817,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user817@example.org +cn: user817 +sn: user817 +description: Generated user +uid: user817 +uidNumber: 10817 +gidNumber: 1 +homeDirectory: /home/user817 + +dn: cn=user818,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user818@example.org +cn: user818 +sn: user818 +description: Generated user +uid: user818 +uidNumber: 10818 +gidNumber: 1 +homeDirectory: /home/user818 + +dn: cn=user819,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user819@example.org +cn: user819 +sn: user819 +description: Generated user +uid: user819 +uidNumber: 10819 +gidNumber: 1 +homeDirectory: /home/user819 + +dn: cn=user820,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user820@example.org +cn: user820 +sn: user820 +description: Generated user +uid: user820 +uidNumber: 10820 +gidNumber: 1 +homeDirectory: /home/user820 + +dn: cn=user821,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user821@example.org +cn: user821 +sn: user821 +description: Generated user +uid: user821 +uidNumber: 10821 +gidNumber: 1 +homeDirectory: /home/user821 + +dn: cn=user822,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user822@example.org +cn: user822 +sn: user822 +description: Generated user +uid: user822 +uidNumber: 10822 +gidNumber: 1 +homeDirectory: /home/user822 + +dn: cn=user823,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user823@example.org +cn: user823 +sn: user823 +description: Generated user +uid: user823 +uidNumber: 10823 +gidNumber: 1 +homeDirectory: /home/user823 + +dn: cn=user824,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user824@example.org +cn: user824 +sn: user824 +description: Generated user +uid: user824 +uidNumber: 10824 +gidNumber: 1 +homeDirectory: /home/user824 + +dn: cn=user825,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user825@example.org +cn: user825 +sn: user825 +description: Generated user +uid: user825 +uidNumber: 10825 +gidNumber: 1 +homeDirectory: /home/user825 + +dn: cn=user826,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user826@example.org +cn: user826 +sn: user826 +description: Generated user +uid: user826 +uidNumber: 10826 +gidNumber: 1 +homeDirectory: /home/user826 + +dn: cn=user827,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user827@example.org +cn: user827 +sn: user827 +description: Generated user +uid: user827 +uidNumber: 10827 +gidNumber: 1 +homeDirectory: /home/user827 + +dn: cn=user828,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user828@example.org +cn: user828 +sn: user828 +description: Generated user +uid: user828 +uidNumber: 10828 +gidNumber: 1 +homeDirectory: /home/user828 + +dn: cn=user829,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user829@example.org +cn: user829 +sn: user829 +description: Generated user +uid: user829 +uidNumber: 10829 +gidNumber: 1 +homeDirectory: /home/user829 + +dn: cn=user830,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user830@example.org +cn: user830 +sn: user830 +description: Generated user +uid: user830 +uidNumber: 10830 +gidNumber: 1 +homeDirectory: /home/user830 + +dn: cn=user831,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user831@example.org +cn: user831 +sn: user831 +description: Generated user +uid: user831 +uidNumber: 10831 +gidNumber: 1 +homeDirectory: /home/user831 + +dn: cn=user832,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user832@example.org +cn: user832 +sn: user832 +description: Generated user +uid: user832 +uidNumber: 10832 +gidNumber: 1 +homeDirectory: /home/user832 + +dn: cn=user833,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user833@example.org +cn: user833 +sn: user833 +description: Generated user +uid: user833 +uidNumber: 10833 +gidNumber: 1 +homeDirectory: /home/user833 + +dn: cn=user834,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user834@example.org +cn: user834 +sn: user834 +description: Generated user +uid: user834 +uidNumber: 10834 +gidNumber: 1 +homeDirectory: /home/user834 + +dn: cn=user835,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user835@example.org +cn: user835 +sn: user835 +description: Generated user +uid: user835 +uidNumber: 10835 +gidNumber: 1 +homeDirectory: /home/user835 + +dn: cn=user836,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user836@example.org +cn: user836 +sn: user836 +description: Generated user +uid: user836 +uidNumber: 10836 +gidNumber: 1 +homeDirectory: /home/user836 + +dn: cn=user837,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user837@example.org +cn: user837 +sn: user837 +description: Generated user +uid: user837 +uidNumber: 10837 +gidNumber: 1 +homeDirectory: /home/user837 + +dn: cn=user838,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user838@example.org +cn: user838 +sn: user838 +description: Generated user +uid: user838 +uidNumber: 10838 +gidNumber: 1 +homeDirectory: /home/user838 + +dn: cn=user839,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user839@example.org +cn: user839 +sn: user839 +description: Generated user +uid: user839 +uidNumber: 10839 +gidNumber: 1 +homeDirectory: /home/user839 + +dn: cn=user840,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user840@example.org +cn: user840 +sn: user840 +description: Generated user +uid: user840 +uidNumber: 10840 +gidNumber: 1 +homeDirectory: /home/user840 + +dn: cn=user841,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user841@example.org +cn: user841 +sn: user841 +description: Generated user +uid: user841 +uidNumber: 10841 +gidNumber: 1 +homeDirectory: /home/user841 + +dn: cn=user842,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user842@example.org +cn: user842 +sn: user842 +description: Generated user +uid: user842 +uidNumber: 10842 +gidNumber: 1 +homeDirectory: /home/user842 + +dn: cn=user843,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user843@example.org +cn: user843 +sn: user843 +description: Generated user +uid: user843 +uidNumber: 10843 +gidNumber: 1 +homeDirectory: /home/user843 + +dn: cn=user844,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user844@example.org +cn: user844 +sn: user844 +description: Generated user +uid: user844 +uidNumber: 10844 +gidNumber: 1 +homeDirectory: /home/user844 + +dn: cn=user845,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user845@example.org +cn: user845 +sn: user845 +description: Generated user +uid: user845 +uidNumber: 10845 +gidNumber: 1 +homeDirectory: /home/user845 + +dn: cn=user846,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user846@example.org +cn: user846 +sn: user846 +description: Generated user +uid: user846 +uidNumber: 10846 +gidNumber: 1 +homeDirectory: /home/user846 + +dn: cn=user847,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user847@example.org +cn: user847 +sn: user847 +description: Generated user +uid: user847 +uidNumber: 10847 +gidNumber: 1 +homeDirectory: /home/user847 + +dn: cn=user848,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user848@example.org +cn: user848 +sn: user848 +description: Generated user +uid: user848 +uidNumber: 10848 +gidNumber: 1 +homeDirectory: /home/user848 + +dn: cn=user849,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user849@example.org +cn: user849 +sn: user849 +description: Generated user +uid: user849 +uidNumber: 10849 +gidNumber: 1 +homeDirectory: /home/user849 + +dn: cn=user850,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user850@example.org +cn: user850 +sn: user850 +description: Generated user +uid: user850 +uidNumber: 10850 +gidNumber: 1 +homeDirectory: /home/user850 + +dn: cn=user851,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user851@example.org +cn: user851 +sn: user851 +description: Generated user +uid: user851 +uidNumber: 10851 +gidNumber: 1 +homeDirectory: /home/user851 + +dn: cn=user852,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user852@example.org +cn: user852 +sn: user852 +description: Generated user +uid: user852 +uidNumber: 10852 +gidNumber: 1 +homeDirectory: /home/user852 + +dn: cn=user853,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user853@example.org +cn: user853 +sn: user853 +description: Generated user +uid: user853 +uidNumber: 10853 +gidNumber: 1 +homeDirectory: /home/user853 + +dn: cn=user854,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user854@example.org +cn: user854 +sn: user854 +description: Generated user +uid: user854 +uidNumber: 10854 +gidNumber: 1 +homeDirectory: /home/user854 + +dn: cn=user855,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user855@example.org +cn: user855 +sn: user855 +description: Generated user +uid: user855 +uidNumber: 10855 +gidNumber: 1 +homeDirectory: /home/user855 + +dn: cn=user856,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user856@example.org +cn: user856 +sn: user856 +description: Generated user +uid: user856 +uidNumber: 10856 +gidNumber: 1 +homeDirectory: /home/user856 + +dn: cn=user857,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user857@example.org +cn: user857 +sn: user857 +description: Generated user +uid: user857 +uidNumber: 10857 +gidNumber: 1 +homeDirectory: /home/user857 + +dn: cn=user858,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user858@example.org +cn: user858 +sn: user858 +description: Generated user +uid: user858 +uidNumber: 10858 +gidNumber: 1 +homeDirectory: /home/user858 + +dn: cn=user859,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user859@example.org +cn: user859 +sn: user859 +description: Generated user +uid: user859 +uidNumber: 10859 +gidNumber: 1 +homeDirectory: /home/user859 + +dn: cn=user860,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user860@example.org +cn: user860 +sn: user860 +description: Generated user +uid: user860 +uidNumber: 10860 +gidNumber: 1 +homeDirectory: /home/user860 + +dn: cn=user861,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user861@example.org +cn: user861 +sn: user861 +description: Generated user +uid: user861 +uidNumber: 10861 +gidNumber: 1 +homeDirectory: /home/user861 + +dn: cn=user862,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user862@example.org +cn: user862 +sn: user862 +description: Generated user +uid: user862 +uidNumber: 10862 +gidNumber: 1 +homeDirectory: /home/user862 + +dn: cn=user863,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user863@example.org +cn: user863 +sn: user863 +description: Generated user +uid: user863 +uidNumber: 10863 +gidNumber: 1 +homeDirectory: /home/user863 + +dn: cn=user864,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user864@example.org +cn: user864 +sn: user864 +description: Generated user +uid: user864 +uidNumber: 10864 +gidNumber: 1 +homeDirectory: /home/user864 + +dn: cn=user865,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user865@example.org +cn: user865 +sn: user865 +description: Generated user +uid: user865 +uidNumber: 10865 +gidNumber: 1 +homeDirectory: /home/user865 + +dn: cn=user866,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user866@example.org +cn: user866 +sn: user866 +description: Generated user +uid: user866 +uidNumber: 10866 +gidNumber: 1 +homeDirectory: /home/user866 + +dn: cn=user867,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user867@example.org +cn: user867 +sn: user867 +description: Generated user +uid: user867 +uidNumber: 10867 +gidNumber: 1 +homeDirectory: /home/user867 + +dn: cn=user868,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user868@example.org +cn: user868 +sn: user868 +description: Generated user +uid: user868 +uidNumber: 10868 +gidNumber: 1 +homeDirectory: /home/user868 + +dn: cn=user869,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user869@example.org +cn: user869 +sn: user869 +description: Generated user +uid: user869 +uidNumber: 10869 +gidNumber: 1 +homeDirectory: /home/user869 + +dn: cn=user870,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user870@example.org +cn: user870 +sn: user870 +description: Generated user +uid: user870 +uidNumber: 10870 +gidNumber: 1 +homeDirectory: /home/user870 + +dn: cn=user871,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user871@example.org +cn: user871 +sn: user871 +description: Generated user +uid: user871 +uidNumber: 10871 +gidNumber: 1 +homeDirectory: /home/user871 + +dn: cn=user872,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user872@example.org +cn: user872 +sn: user872 +description: Generated user +uid: user872 +uidNumber: 10872 +gidNumber: 1 +homeDirectory: /home/user872 + +dn: cn=user873,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user873@example.org +cn: user873 +sn: user873 +description: Generated user +uid: user873 +uidNumber: 10873 +gidNumber: 1 +homeDirectory: /home/user873 + +dn: cn=user874,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user874@example.org +cn: user874 +sn: user874 +description: Generated user +uid: user874 +uidNumber: 10874 +gidNumber: 1 +homeDirectory: /home/user874 + +dn: cn=user875,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user875@example.org +cn: user875 +sn: user875 +description: Generated user +uid: user875 +uidNumber: 10875 +gidNumber: 1 +homeDirectory: /home/user875 + +dn: cn=user876,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user876@example.org +cn: user876 +sn: user876 +description: Generated user +uid: user876 +uidNumber: 10876 +gidNumber: 1 +homeDirectory: /home/user876 + +dn: cn=user877,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user877@example.org +cn: user877 +sn: user877 +description: Generated user +uid: user877 +uidNumber: 10877 +gidNumber: 1 +homeDirectory: /home/user877 + +dn: cn=user878,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user878@example.org +cn: user878 +sn: user878 +description: Generated user +uid: user878 +uidNumber: 10878 +gidNumber: 1 +homeDirectory: /home/user878 + +dn: cn=user879,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user879@example.org +cn: user879 +sn: user879 +description: Generated user +uid: user879 +uidNumber: 10879 +gidNumber: 1 +homeDirectory: /home/user879 + +dn: cn=user880,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user880@example.org +cn: user880 +sn: user880 +description: Generated user +uid: user880 +uidNumber: 10880 +gidNumber: 1 +homeDirectory: /home/user880 + +dn: cn=user881,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user881@example.org +cn: user881 +sn: user881 +description: Generated user +uid: user881 +uidNumber: 10881 +gidNumber: 1 +homeDirectory: /home/user881 + +dn: cn=user882,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user882@example.org +cn: user882 +sn: user882 +description: Generated user +uid: user882 +uidNumber: 10882 +gidNumber: 1 +homeDirectory: /home/user882 + +dn: cn=user883,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user883@example.org +cn: user883 +sn: user883 +description: Generated user +uid: user883 +uidNumber: 10883 +gidNumber: 1 +homeDirectory: /home/user883 + +dn: cn=user884,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user884@example.org +cn: user884 +sn: user884 +description: Generated user +uid: user884 +uidNumber: 10884 +gidNumber: 1 +homeDirectory: /home/user884 + +dn: cn=user885,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user885@example.org +cn: user885 +sn: user885 +description: Generated user +uid: user885 +uidNumber: 10885 +gidNumber: 1 +homeDirectory: /home/user885 + +dn: cn=user886,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user886@example.org +cn: user886 +sn: user886 +description: Generated user +uid: user886 +uidNumber: 10886 +gidNumber: 1 +homeDirectory: /home/user886 + +dn: cn=user887,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user887@example.org +cn: user887 +sn: user887 +description: Generated user +uid: user887 +uidNumber: 10887 +gidNumber: 1 +homeDirectory: /home/user887 + +dn: cn=user888,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user888@example.org +cn: user888 +sn: user888 +description: Generated user +uid: user888 +uidNumber: 10888 +gidNumber: 1 +homeDirectory: /home/user888 + +dn: cn=user889,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user889@example.org +cn: user889 +sn: user889 +description: Generated user +uid: user889 +uidNumber: 10889 +gidNumber: 1 +homeDirectory: /home/user889 + +dn: cn=user890,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user890@example.org +cn: user890 +sn: user890 +description: Generated user +uid: user890 +uidNumber: 10890 +gidNumber: 1 +homeDirectory: /home/user890 + +dn: cn=user891,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user891@example.org +cn: user891 +sn: user891 +description: Generated user +uid: user891 +uidNumber: 10891 +gidNumber: 1 +homeDirectory: /home/user891 + +dn: cn=user892,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user892@example.org +cn: user892 +sn: user892 +description: Generated user +uid: user892 +uidNumber: 10892 +gidNumber: 1 +homeDirectory: /home/user892 + +dn: cn=user893,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user893@example.org +cn: user893 +sn: user893 +description: Generated user +uid: user893 +uidNumber: 10893 +gidNumber: 1 +homeDirectory: /home/user893 + +dn: cn=user894,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user894@example.org +cn: user894 +sn: user894 +description: Generated user +uid: user894 +uidNumber: 10894 +gidNumber: 1 +homeDirectory: /home/user894 + +dn: cn=user895,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user895@example.org +cn: user895 +sn: user895 +description: Generated user +uid: user895 +uidNumber: 10895 +gidNumber: 1 +homeDirectory: /home/user895 + +dn: cn=user896,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user896@example.org +cn: user896 +sn: user896 +description: Generated user +uid: user896 +uidNumber: 10896 +gidNumber: 1 +homeDirectory: /home/user896 + +dn: cn=user897,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user897@example.org +cn: user897 +sn: user897 +description: Generated user +uid: user897 +uidNumber: 10897 +gidNumber: 1 +homeDirectory: /home/user897 + +dn: cn=user898,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user898@example.org +cn: user898 +sn: user898 +description: Generated user +uid: user898 +uidNumber: 10898 +gidNumber: 1 +homeDirectory: /home/user898 + +dn: cn=user899,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user899@example.org +cn: user899 +sn: user899 +description: Generated user +uid: user899 +uidNumber: 10899 +gidNumber: 1 +homeDirectory: /home/user899 + +dn: cn=user900,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user900@example.org +cn: user900 +sn: user900 +description: Generated user +uid: user900 +uidNumber: 10900 +gidNumber: 1 +homeDirectory: /home/user900 + +dn: cn=user901,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user901@example.org +cn: user901 +sn: user901 +description: Generated user +uid: user901 +uidNumber: 10901 +gidNumber: 1 +homeDirectory: /home/user901 + +dn: cn=user902,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user902@example.org +cn: user902 +sn: user902 +description: Generated user +uid: user902 +uidNumber: 10902 +gidNumber: 1 +homeDirectory: /home/user902 + +dn: cn=user903,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user903@example.org +cn: user903 +sn: user903 +description: Generated user +uid: user903 +uidNumber: 10903 +gidNumber: 1 +homeDirectory: /home/user903 + +dn: cn=user904,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user904@example.org +cn: user904 +sn: user904 +description: Generated user +uid: user904 +uidNumber: 10904 +gidNumber: 1 +homeDirectory: /home/user904 + +dn: cn=user905,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user905@example.org +cn: user905 +sn: user905 +description: Generated user +uid: user905 +uidNumber: 10905 +gidNumber: 1 +homeDirectory: /home/user905 + +dn: cn=user906,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user906@example.org +cn: user906 +sn: user906 +description: Generated user +uid: user906 +uidNumber: 10906 +gidNumber: 1 +homeDirectory: /home/user906 + +dn: cn=user907,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user907@example.org +cn: user907 +sn: user907 +description: Generated user +uid: user907 +uidNumber: 10907 +gidNumber: 1 +homeDirectory: /home/user907 + +dn: cn=user908,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user908@example.org +cn: user908 +sn: user908 +description: Generated user +uid: user908 +uidNumber: 10908 +gidNumber: 1 +homeDirectory: /home/user908 + +dn: cn=user909,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user909@example.org +cn: user909 +sn: user909 +description: Generated user +uid: user909 +uidNumber: 10909 +gidNumber: 1 +homeDirectory: /home/user909 + +dn: cn=user910,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user910@example.org +cn: user910 +sn: user910 +description: Generated user +uid: user910 +uidNumber: 10910 +gidNumber: 1 +homeDirectory: /home/user910 + +dn: cn=user911,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user911@example.org +cn: user911 +sn: user911 +description: Generated user +uid: user911 +uidNumber: 10911 +gidNumber: 1 +homeDirectory: /home/user911 + +dn: cn=user912,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user912@example.org +cn: user912 +sn: user912 +description: Generated user +uid: user912 +uidNumber: 10912 +gidNumber: 1 +homeDirectory: /home/user912 + +dn: cn=user913,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user913@example.org +cn: user913 +sn: user913 +description: Generated user +uid: user913 +uidNumber: 10913 +gidNumber: 1 +homeDirectory: /home/user913 + +dn: cn=user914,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user914@example.org +cn: user914 +sn: user914 +description: Generated user +uid: user914 +uidNumber: 10914 +gidNumber: 1 +homeDirectory: /home/user914 + +dn: cn=user915,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user915@example.org +cn: user915 +sn: user915 +description: Generated user +uid: user915 +uidNumber: 10915 +gidNumber: 1 +homeDirectory: /home/user915 + +dn: cn=user916,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user916@example.org +cn: user916 +sn: user916 +description: Generated user +uid: user916 +uidNumber: 10916 +gidNumber: 1 +homeDirectory: /home/user916 + +dn: cn=user917,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user917@example.org +cn: user917 +sn: user917 +description: Generated user +uid: user917 +uidNumber: 10917 +gidNumber: 1 +homeDirectory: /home/user917 + +dn: cn=user918,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user918@example.org +cn: user918 +sn: user918 +description: Generated user +uid: user918 +uidNumber: 10918 +gidNumber: 1 +homeDirectory: /home/user918 + +dn: cn=user919,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user919@example.org +cn: user919 +sn: user919 +description: Generated user +uid: user919 +uidNumber: 10919 +gidNumber: 1 +homeDirectory: /home/user919 + +dn: cn=user920,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user920@example.org +cn: user920 +sn: user920 +description: Generated user +uid: user920 +uidNumber: 10920 +gidNumber: 1 +homeDirectory: /home/user920 + +dn: cn=user921,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user921@example.org +cn: user921 +sn: user921 +description: Generated user +uid: user921 +uidNumber: 10921 +gidNumber: 1 +homeDirectory: /home/user921 + +dn: cn=user922,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user922@example.org +cn: user922 +sn: user922 +description: Generated user +uid: user922 +uidNumber: 10922 +gidNumber: 1 +homeDirectory: /home/user922 + +dn: cn=user923,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user923@example.org +cn: user923 +sn: user923 +description: Generated user +uid: user923 +uidNumber: 10923 +gidNumber: 1 +homeDirectory: /home/user923 + +dn: cn=user924,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user924@example.org +cn: user924 +sn: user924 +description: Generated user +uid: user924 +uidNumber: 10924 +gidNumber: 1 +homeDirectory: /home/user924 + +dn: cn=user925,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user925@example.org +cn: user925 +sn: user925 +description: Generated user +uid: user925 +uidNumber: 10925 +gidNumber: 1 +homeDirectory: /home/user925 + +dn: cn=user926,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user926@example.org +cn: user926 +sn: user926 +description: Generated user +uid: user926 +uidNumber: 10926 +gidNumber: 1 +homeDirectory: /home/user926 + +dn: cn=user927,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user927@example.org +cn: user927 +sn: user927 +description: Generated user +uid: user927 +uidNumber: 10927 +gidNumber: 1 +homeDirectory: /home/user927 + +dn: cn=user928,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user928@example.org +cn: user928 +sn: user928 +description: Generated user +uid: user928 +uidNumber: 10928 +gidNumber: 1 +homeDirectory: /home/user928 + +dn: cn=user929,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user929@example.org +cn: user929 +sn: user929 +description: Generated user +uid: user929 +uidNumber: 10929 +gidNumber: 1 +homeDirectory: /home/user929 + +dn: cn=user930,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user930@example.org +cn: user930 +sn: user930 +description: Generated user +uid: user930 +uidNumber: 10930 +gidNumber: 1 +homeDirectory: /home/user930 + +dn: cn=user931,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user931@example.org +cn: user931 +sn: user931 +description: Generated user +uid: user931 +uidNumber: 10931 +gidNumber: 1 +homeDirectory: /home/user931 + +dn: cn=user932,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user932@example.org +cn: user932 +sn: user932 +description: Generated user +uid: user932 +uidNumber: 10932 +gidNumber: 1 +homeDirectory: /home/user932 + +dn: cn=user933,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user933@example.org +cn: user933 +sn: user933 +description: Generated user +uid: user933 +uidNumber: 10933 +gidNumber: 1 +homeDirectory: /home/user933 + +dn: cn=user934,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user934@example.org +cn: user934 +sn: user934 +description: Generated user +uid: user934 +uidNumber: 10934 +gidNumber: 1 +homeDirectory: /home/user934 + +dn: cn=user935,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user935@example.org +cn: user935 +sn: user935 +description: Generated user +uid: user935 +uidNumber: 10935 +gidNumber: 1 +homeDirectory: /home/user935 + +dn: cn=user936,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user936@example.org +cn: user936 +sn: user936 +description: Generated user +uid: user936 +uidNumber: 10936 +gidNumber: 1 +homeDirectory: /home/user936 + +dn: cn=user937,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user937@example.org +cn: user937 +sn: user937 +description: Generated user +uid: user937 +uidNumber: 10937 +gidNumber: 1 +homeDirectory: /home/user937 + +dn: cn=user938,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user938@example.org +cn: user938 +sn: user938 +description: Generated user +uid: user938 +uidNumber: 10938 +gidNumber: 1 +homeDirectory: /home/user938 + +dn: cn=user939,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user939@example.org +cn: user939 +sn: user939 +description: Generated user +uid: user939 +uidNumber: 10939 +gidNumber: 1 +homeDirectory: /home/user939 + +dn: cn=user940,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user940@example.org +cn: user940 +sn: user940 +description: Generated user +uid: user940 +uidNumber: 10940 +gidNumber: 1 +homeDirectory: /home/user940 + +dn: cn=user941,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user941@example.org +cn: user941 +sn: user941 +description: Generated user +uid: user941 +uidNumber: 10941 +gidNumber: 1 +homeDirectory: /home/user941 + +dn: cn=user942,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user942@example.org +cn: user942 +sn: user942 +description: Generated user +uid: user942 +uidNumber: 10942 +gidNumber: 1 +homeDirectory: /home/user942 + +dn: cn=user943,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user943@example.org +cn: user943 +sn: user943 +description: Generated user +uid: user943 +uidNumber: 10943 +gidNumber: 1 +homeDirectory: /home/user943 + +dn: cn=user944,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user944@example.org +cn: user944 +sn: user944 +description: Generated user +uid: user944 +uidNumber: 10944 +gidNumber: 1 +homeDirectory: /home/user944 + +dn: cn=user945,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user945@example.org +cn: user945 +sn: user945 +description: Generated user +uid: user945 +uidNumber: 10945 +gidNumber: 1 +homeDirectory: /home/user945 + +dn: cn=user946,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user946@example.org +cn: user946 +sn: user946 +description: Generated user +uid: user946 +uidNumber: 10946 +gidNumber: 1 +homeDirectory: /home/user946 + +dn: cn=user947,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user947@example.org +cn: user947 +sn: user947 +description: Generated user +uid: user947 +uidNumber: 10947 +gidNumber: 1 +homeDirectory: /home/user947 + +dn: cn=user948,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user948@example.org +cn: user948 +sn: user948 +description: Generated user +uid: user948 +uidNumber: 10948 +gidNumber: 1 +homeDirectory: /home/user948 + +dn: cn=user949,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user949@example.org +cn: user949 +sn: user949 +description: Generated user +uid: user949 +uidNumber: 10949 +gidNumber: 1 +homeDirectory: /home/user949 + +dn: cn=user950,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user950@example.org +cn: user950 +sn: user950 +description: Generated user +uid: user950 +uidNumber: 10950 +gidNumber: 1 +homeDirectory: /home/user950 + +dn: cn=user951,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user951@example.org +cn: user951 +sn: user951 +description: Generated user +uid: user951 +uidNumber: 10951 +gidNumber: 1 +homeDirectory: /home/user951 + +dn: cn=user952,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user952@example.org +cn: user952 +sn: user952 +description: Generated user +uid: user952 +uidNumber: 10952 +gidNumber: 1 +homeDirectory: /home/user952 + +dn: cn=user953,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user953@example.org +cn: user953 +sn: user953 +description: Generated user +uid: user953 +uidNumber: 10953 +gidNumber: 1 +homeDirectory: /home/user953 + +dn: cn=user954,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user954@example.org +cn: user954 +sn: user954 +description: Generated user +uid: user954 +uidNumber: 10954 +gidNumber: 1 +homeDirectory: /home/user954 + +dn: cn=user955,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user955@example.org +cn: user955 +sn: user955 +description: Generated user +uid: user955 +uidNumber: 10955 +gidNumber: 1 +homeDirectory: /home/user955 + +dn: cn=user956,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user956@example.org +cn: user956 +sn: user956 +description: Generated user +uid: user956 +uidNumber: 10956 +gidNumber: 1 +homeDirectory: /home/user956 + +dn: cn=user957,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user957@example.org +cn: user957 +sn: user957 +description: Generated user +uid: user957 +uidNumber: 10957 +gidNumber: 1 +homeDirectory: /home/user957 + +dn: cn=user958,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user958@example.org +cn: user958 +sn: user958 +description: Generated user +uid: user958 +uidNumber: 10958 +gidNumber: 1 +homeDirectory: /home/user958 + +dn: cn=user959,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user959@example.org +cn: user959 +sn: user959 +description: Generated user +uid: user959 +uidNumber: 10959 +gidNumber: 1 +homeDirectory: /home/user959 + +dn: cn=user960,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user960@example.org +cn: user960 +sn: user960 +description: Generated user +uid: user960 +uidNumber: 10960 +gidNumber: 1 +homeDirectory: /home/user960 + +dn: cn=user961,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user961@example.org +cn: user961 +sn: user961 +description: Generated user +uid: user961 +uidNumber: 10961 +gidNumber: 1 +homeDirectory: /home/user961 + +dn: cn=user962,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user962@example.org +cn: user962 +sn: user962 +description: Generated user +uid: user962 +uidNumber: 10962 +gidNumber: 1 +homeDirectory: /home/user962 + +dn: cn=user963,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user963@example.org +cn: user963 +sn: user963 +description: Generated user +uid: user963 +uidNumber: 10963 +gidNumber: 1 +homeDirectory: /home/user963 + +dn: cn=user964,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user964@example.org +cn: user964 +sn: user964 +description: Generated user +uid: user964 +uidNumber: 10964 +gidNumber: 1 +homeDirectory: /home/user964 + +dn: cn=user965,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user965@example.org +cn: user965 +sn: user965 +description: Generated user +uid: user965 +uidNumber: 10965 +gidNumber: 1 +homeDirectory: /home/user965 + +dn: cn=user966,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user966@example.org +cn: user966 +sn: user966 +description: Generated user +uid: user966 +uidNumber: 10966 +gidNumber: 1 +homeDirectory: /home/user966 + +dn: cn=user967,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user967@example.org +cn: user967 +sn: user967 +description: Generated user +uid: user967 +uidNumber: 10967 +gidNumber: 1 +homeDirectory: /home/user967 + +dn: cn=user968,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user968@example.org +cn: user968 +sn: user968 +description: Generated user +uid: user968 +uidNumber: 10968 +gidNumber: 1 +homeDirectory: /home/user968 + +dn: cn=user969,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user969@example.org +cn: user969 +sn: user969 +description: Generated user +uid: user969 +uidNumber: 10969 +gidNumber: 1 +homeDirectory: /home/user969 + +dn: cn=user970,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user970@example.org +cn: user970 +sn: user970 +description: Generated user +uid: user970 +uidNumber: 10970 +gidNumber: 1 +homeDirectory: /home/user970 + +dn: cn=user971,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user971@example.org +cn: user971 +sn: user971 +description: Generated user +uid: user971 +uidNumber: 10971 +gidNumber: 1 +homeDirectory: /home/user971 + +dn: cn=user972,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user972@example.org +cn: user972 +sn: user972 +description: Generated user +uid: user972 +uidNumber: 10972 +gidNumber: 1 +homeDirectory: /home/user972 + +dn: cn=user973,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user973@example.org +cn: user973 +sn: user973 +description: Generated user +uid: user973 +uidNumber: 10973 +gidNumber: 1 +homeDirectory: /home/user973 + +dn: cn=user974,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user974@example.org +cn: user974 +sn: user974 +description: Generated user +uid: user974 +uidNumber: 10974 +gidNumber: 1 +homeDirectory: /home/user974 + +dn: cn=user975,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user975@example.org +cn: user975 +sn: user975 +description: Generated user +uid: user975 +uidNumber: 10975 +gidNumber: 1 +homeDirectory: /home/user975 + +dn: cn=user976,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user976@example.org +cn: user976 +sn: user976 +description: Generated user +uid: user976 +uidNumber: 10976 +gidNumber: 1 +homeDirectory: /home/user976 + +dn: cn=user977,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user977@example.org +cn: user977 +sn: user977 +description: Generated user +uid: user977 +uidNumber: 10977 +gidNumber: 1 +homeDirectory: /home/user977 + +dn: cn=user978,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user978@example.org +cn: user978 +sn: user978 +description: Generated user +uid: user978 +uidNumber: 10978 +gidNumber: 1 +homeDirectory: /home/user978 + +dn: cn=user979,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user979@example.org +cn: user979 +sn: user979 +description: Generated user +uid: user979 +uidNumber: 10979 +gidNumber: 1 +homeDirectory: /home/user979 + +dn: cn=user980,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user980@example.org +cn: user980 +sn: user980 +description: Generated user +uid: user980 +uidNumber: 10980 +gidNumber: 1 +homeDirectory: /home/user980 + +dn: cn=user981,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user981@example.org +cn: user981 +sn: user981 +description: Generated user +uid: user981 +uidNumber: 10981 +gidNumber: 1 +homeDirectory: /home/user981 + +dn: cn=user982,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user982@example.org +cn: user982 +sn: user982 +description: Generated user +uid: user982 +uidNumber: 10982 +gidNumber: 1 +homeDirectory: /home/user982 + +dn: cn=user983,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user983@example.org +cn: user983 +sn: user983 +description: Generated user +uid: user983 +uidNumber: 10983 +gidNumber: 1 +homeDirectory: /home/user983 + +dn: cn=user984,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user984@example.org +cn: user984 +sn: user984 +description: Generated user +uid: user984 +uidNumber: 10984 +gidNumber: 1 +homeDirectory: /home/user984 + +dn: cn=user985,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user985@example.org +cn: user985 +sn: user985 +description: Generated user +uid: user985 +uidNumber: 10985 +gidNumber: 1 +homeDirectory: /home/user985 + +dn: cn=user986,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user986@example.org +cn: user986 +sn: user986 +description: Generated user +uid: user986 +uidNumber: 10986 +gidNumber: 1 +homeDirectory: /home/user986 + +dn: cn=user987,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user987@example.org +cn: user987 +sn: user987 +description: Generated user +uid: user987 +uidNumber: 10987 +gidNumber: 1 +homeDirectory: /home/user987 + +dn: cn=user988,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user988@example.org +cn: user988 +sn: user988 +description: Generated user +uid: user988 +uidNumber: 10988 +gidNumber: 1 +homeDirectory: /home/user988 + +dn: cn=user989,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user989@example.org +cn: user989 +sn: user989 +description: Generated user +uid: user989 +uidNumber: 10989 +gidNumber: 1 +homeDirectory: /home/user989 + +dn: cn=user990,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user990@example.org +cn: user990 +sn: user990 +description: Generated user +uid: user990 +uidNumber: 10990 +gidNumber: 1 +homeDirectory: /home/user990 + +dn: cn=user991,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user991@example.org +cn: user991 +sn: user991 +description: Generated user +uid: user991 +uidNumber: 10991 +gidNumber: 1 +homeDirectory: /home/user991 + +dn: cn=user992,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user992@example.org +cn: user992 +sn: user992 +description: Generated user +uid: user992 +uidNumber: 10992 +gidNumber: 1 +homeDirectory: /home/user992 + +dn: cn=user993,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user993@example.org +cn: user993 +sn: user993 +description: Generated user +uid: user993 +uidNumber: 10993 +gidNumber: 1 +homeDirectory: /home/user993 + +dn: cn=user994,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user994@example.org +cn: user994 +sn: user994 +description: Generated user +uid: user994 +uidNumber: 10994 +gidNumber: 1 +homeDirectory: /home/user994 + +dn: cn=user995,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user995@example.org +cn: user995 +sn: user995 +description: Generated user +uid: user995 +uidNumber: 10995 +gidNumber: 1 +homeDirectory: /home/user995 + +dn: cn=user996,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user996@example.org +cn: user996 +sn: user996 +description: Generated user +uid: user996 +uidNumber: 10996 +gidNumber: 1 +homeDirectory: /home/user996 + +dn: cn=user997,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user997@example.org +cn: user997 +sn: user997 +description: Generated user +uid: user997 +uidNumber: 10997 +gidNumber: 1 +homeDirectory: /home/user997 + +dn: cn=user998,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user998@example.org +cn: user998 +sn: user998 +description: Generated user +uid: user998 +uidNumber: 10998 +gidNumber: 1 +homeDirectory: /home/user998 + +dn: cn=user999,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user999@example.org +cn: user999 +sn: user999 +description: Generated user +uid: user999 +uidNumber: 10999 +gidNumber: 1 +homeDirectory: /home/user999 + +dn: cn=user1000,dc=example,dc=org +objectClass: top +objectClass: person +objectClass: posixAccount +objectClass: ldapPublicKey +sshPublicKey: ssh-rsa blahblah user1000@example.org +cn: user1000 +sn: user1000 +description: Generated user +uid: user1000 +uidNumber: 11000 +gidNumber: 1 +homeDirectory: /home/user1000 + +dn: cn=group1,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group1 +gidNumber: 10001 +memberUid: user1 +memberUid: user2 +memberUid: user3 +memberUid: user4 +memberUid: user5 +memberUid: user6 +memberUid: user7 +memberUid: user8 +memberUid: user9 +memberUid: user10 +memberUid: user11 +memberUid: user12 +memberUid: user13 +memberUid: user14 +memberUid: user15 +memberUid: user16 +memberUid: user17 +memberUid: user18 +memberUid: user19 +memberUid: user20 +memberUid: user21 +memberUid: user22 +memberUid: user23 +memberUid: user24 +memberUid: user25 +memberUid: user26 +memberUid: user27 +memberUid: user28 +memberUid: user29 +memberUid: user30 +memberUid: user31 +memberUid: user32 +memberUid: user33 +memberUid: user34 +memberUid: user35 +memberUid: user36 +memberUid: user37 +memberUid: user38 +memberUid: user39 +memberUid: user40 +memberUid: user41 +memberUid: user42 +memberUid: user43 +memberUid: user44 +memberUid: user45 +memberUid: user46 +memberUid: user47 +memberUid: user48 +memberUid: user49 +memberUid: user50 +memberUid: user51 +memberUid: user52 +memberUid: user53 +memberUid: user54 +memberUid: user55 +memberUid: user56 +memberUid: user57 +memberUid: user58 +memberUid: user59 +memberUid: user60 +memberUid: user61 +memberUid: user62 +memberUid: user63 +memberUid: user64 +memberUid: user65 +memberUid: user66 +memberUid: user67 +memberUid: user68 +memberUid: user69 +memberUid: user70 +memberUid: user71 +memberUid: user72 +memberUid: user73 +memberUid: user74 +memberUid: user75 +memberUid: user76 +memberUid: user77 +memberUid: user78 +memberUid: user79 +memberUid: user80 +memberUid: user81 +memberUid: user82 +memberUid: user83 +memberUid: user84 +memberUid: user85 +memberUid: user86 +memberUid: user87 +memberUid: user88 +memberUid: user89 +memberUid: user90 +memberUid: user91 +memberUid: user92 +memberUid: user93 +memberUid: user94 +memberUid: user95 +memberUid: user96 +memberUid: user97 +memberUid: user98 +memberUid: user99 +memberUid: user100 +memberUid: user101 +memberUid: user102 +memberUid: user103 +memberUid: user104 +memberUid: user105 +memberUid: user106 +memberUid: user107 +memberUid: user108 +memberUid: user109 +memberUid: user110 +memberUid: user111 +memberUid: user112 +memberUid: user113 +memberUid: user114 +memberUid: user115 +memberUid: user116 +memberUid: user117 +memberUid: user118 +memberUid: user119 +memberUid: user120 +memberUid: user121 +memberUid: user122 +memberUid: user123 +memberUid: user124 +memberUid: user125 +memberUid: user126 +memberUid: user127 +memberUid: user128 +memberUid: user129 +memberUid: user130 +memberUid: user131 +memberUid: user132 +memberUid: user133 +memberUid: user134 +memberUid: user135 +memberUid: user136 +memberUid: user137 +memberUid: user138 +memberUid: user139 +memberUid: user140 +memberUid: user141 +memberUid: user142 +memberUid: user143 +memberUid: user144 +memberUid: user145 +memberUid: user146 +memberUid: user147 +memberUid: user148 +memberUid: user149 +memberUid: user150 +memberUid: user151 +memberUid: user152 +memberUid: user153 +memberUid: user154 +memberUid: user155 +memberUid: user156 +memberUid: user157 +memberUid: user158 +memberUid: user159 +memberUid: user160 +memberUid: user161 +memberUid: user162 +memberUid: user163 +memberUid: user164 +memberUid: user165 +memberUid: user166 +memberUid: user167 +memberUid: user168 +memberUid: user169 +memberUid: user170 +memberUid: user171 +memberUid: user172 +memberUid: user173 +memberUid: user174 +memberUid: user175 +memberUid: user176 +memberUid: user177 +memberUid: user178 +memberUid: user179 +memberUid: user180 +memberUid: user181 +memberUid: user182 +memberUid: user183 +memberUid: user184 +memberUid: user185 +memberUid: user186 +memberUid: user187 +memberUid: user188 +memberUid: user189 +memberUid: user190 +memberUid: user191 +memberUid: user192 +memberUid: user193 +memberUid: user194 +memberUid: user195 +memberUid: user196 +memberUid: user197 +memberUid: user198 +memberUid: user199 +memberUid: user200 +memberUid: user201 +memberUid: user202 +memberUid: user203 +memberUid: user204 +memberUid: user205 +memberUid: user206 +memberUid: user207 +memberUid: user208 +memberUid: user209 +memberUid: user210 +memberUid: user211 +memberUid: user212 +memberUid: user213 +memberUid: user214 +memberUid: user215 +memberUid: user216 +memberUid: user217 +memberUid: user218 +memberUid: user219 +memberUid: user220 +memberUid: user221 +memberUid: user222 +memberUid: user223 +memberUid: user224 +memberUid: user225 +memberUid: user226 +memberUid: user227 +memberUid: user228 +memberUid: user229 +memberUid: user230 +memberUid: user231 +memberUid: user232 +memberUid: user233 +memberUid: user234 +memberUid: user235 +memberUid: user236 +memberUid: user237 +memberUid: user238 +memberUid: user239 +memberUid: user240 +memberUid: user241 +memberUid: user242 +memberUid: user243 +memberUid: user244 +memberUid: user245 +memberUid: user246 +memberUid: user247 +memberUid: user248 +memberUid: user249 +memberUid: user250 +memberUid: user251 +memberUid: user252 +memberUid: user253 +memberUid: user254 +memberUid: user255 +memberUid: user256 +memberUid: user257 +memberUid: user258 +memberUid: user259 +memberUid: user260 +memberUid: user261 +memberUid: user262 +memberUid: user263 +memberUid: user264 +memberUid: user265 +memberUid: user266 +memberUid: user267 +memberUid: user268 +memberUid: user269 +memberUid: user270 +memberUid: user271 +memberUid: user272 +memberUid: user273 +memberUid: user274 +memberUid: user275 +memberUid: user276 +memberUid: user277 +memberUid: user278 +memberUid: user279 +memberUid: user280 +memberUid: user281 +memberUid: user282 +memberUid: user283 +memberUid: user284 +memberUid: user285 +memberUid: user286 +memberUid: user287 +memberUid: user288 +memberUid: user289 +memberUid: user290 +memberUid: user291 +memberUid: user292 +memberUid: user293 +memberUid: user294 +memberUid: user295 +memberUid: user296 +memberUid: user297 +memberUid: user298 +memberUid: user299 +memberUid: user300 +memberUid: user301 +memberUid: user302 +memberUid: user303 +memberUid: user304 +memberUid: user305 +memberUid: user306 +memberUid: user307 +memberUid: user308 +memberUid: user309 +memberUid: user310 +memberUid: user311 +memberUid: user312 +memberUid: user313 +memberUid: user314 +memberUid: user315 +memberUid: user316 +memberUid: user317 +memberUid: user318 +memberUid: user319 +memberUid: user320 +memberUid: user321 +memberUid: user322 +memberUid: user323 +memberUid: user324 +memberUid: user325 +memberUid: user326 +memberUid: user327 +memberUid: user328 +memberUid: user329 +memberUid: user330 +memberUid: user331 +memberUid: user332 +memberUid: user333 +memberUid: user334 +memberUid: user335 +memberUid: user336 +memberUid: user337 +memberUid: user338 +memberUid: user339 +memberUid: user340 +memberUid: user341 +memberUid: user342 +memberUid: user343 +memberUid: user344 +memberUid: user345 +memberUid: user346 +memberUid: user347 +memberUid: user348 +memberUid: user349 +memberUid: user350 +memberUid: user351 +memberUid: user352 +memberUid: user353 +memberUid: user354 +memberUid: user355 +memberUid: user356 +memberUid: user357 +memberUid: user358 +memberUid: user359 +memberUid: user360 +memberUid: user361 +memberUid: user362 +memberUid: user363 +memberUid: user364 +memberUid: user365 +memberUid: user366 +memberUid: user367 +memberUid: user368 +memberUid: user369 +memberUid: user370 +memberUid: user371 +memberUid: user372 +memberUid: user373 +memberUid: user374 +memberUid: user375 +memberUid: user376 +memberUid: user377 +memberUid: user378 +memberUid: user379 +memberUid: user380 +memberUid: user381 +memberUid: user382 +memberUid: user383 +memberUid: user384 +memberUid: user385 +memberUid: user386 +memberUid: user387 +memberUid: user388 +memberUid: user389 +memberUid: user390 +memberUid: user391 +memberUid: user392 +memberUid: user393 +memberUid: user394 +memberUid: user395 +memberUid: user396 +memberUid: user397 +memberUid: user398 +memberUid: user399 +memberUid: user400 +memberUid: user401 +memberUid: user402 +memberUid: user403 +memberUid: user404 +memberUid: user405 +memberUid: user406 +memberUid: user407 +memberUid: user408 +memberUid: user409 +memberUid: user410 +memberUid: user411 +memberUid: user412 +memberUid: user413 +memberUid: user414 +memberUid: user415 +memberUid: user416 +memberUid: user417 +memberUid: user418 +memberUid: user419 +memberUid: user420 +memberUid: user421 +memberUid: user422 +memberUid: user423 +memberUid: user424 +memberUid: user425 +memberUid: user426 +memberUid: user427 +memberUid: user428 +memberUid: user429 +memberUid: user430 +memberUid: user431 +memberUid: user432 +memberUid: user433 +memberUid: user434 +memberUid: user435 +memberUid: user436 +memberUid: user437 +memberUid: user438 +memberUid: user439 +memberUid: user440 +memberUid: user441 +memberUid: user442 +memberUid: user443 +memberUid: user444 +memberUid: user445 +memberUid: user446 +memberUid: user447 +memberUid: user448 +memberUid: user449 +memberUid: user450 +memberUid: user451 +memberUid: user452 +memberUid: user453 +memberUid: user454 +memberUid: user455 +memberUid: user456 +memberUid: user457 +memberUid: user458 +memberUid: user459 +memberUid: user460 +memberUid: user461 +memberUid: user462 +memberUid: user463 +memberUid: user464 +memberUid: user465 +memberUid: user466 +memberUid: user467 +memberUid: user468 +memberUid: user469 +memberUid: user470 +memberUid: user471 +memberUid: user472 +memberUid: user473 +memberUid: user474 +memberUid: user475 +memberUid: user476 +memberUid: user477 +memberUid: user478 +memberUid: user479 +memberUid: user480 +memberUid: user481 +memberUid: user482 +memberUid: user483 +memberUid: user484 +memberUid: user485 +memberUid: user486 +memberUid: user487 +memberUid: user488 +memberUid: user489 +memberUid: user490 +memberUid: user491 +memberUid: user492 +memberUid: user493 +memberUid: user494 +memberUid: user495 +memberUid: user496 +memberUid: user497 +memberUid: user498 +memberUid: user499 +memberUid: user500 +memberUid: user501 +memberUid: user502 +memberUid: user503 +memberUid: user504 +memberUid: user505 +memberUid: user506 +memberUid: user507 +memberUid: user508 +memberUid: user509 +memberUid: user510 +memberUid: user511 +memberUid: user512 +memberUid: user513 +memberUid: user514 +memberUid: user515 +memberUid: user516 +memberUid: user517 +memberUid: user518 +memberUid: user519 +memberUid: user520 +memberUid: user521 +memberUid: user522 +memberUid: user523 +memberUid: user524 +memberUid: user525 +memberUid: user526 +memberUid: user527 +memberUid: user528 +memberUid: user529 +memberUid: user530 +memberUid: user531 +memberUid: user532 +memberUid: user533 +memberUid: user534 +memberUid: user535 +memberUid: user536 +memberUid: user537 +memberUid: user538 +memberUid: user539 +memberUid: user540 +memberUid: user541 +memberUid: user542 +memberUid: user543 +memberUid: user544 +memberUid: user545 +memberUid: user546 +memberUid: user547 +memberUid: user548 +memberUid: user549 +memberUid: user550 +memberUid: user551 +memberUid: user552 +memberUid: user553 +memberUid: user554 +memberUid: user555 +memberUid: user556 +memberUid: user557 +memberUid: user558 +memberUid: user559 +memberUid: user560 +memberUid: user561 +memberUid: user562 +memberUid: user563 +memberUid: user564 +memberUid: user565 +memberUid: user566 +memberUid: user567 +memberUid: user568 +memberUid: user569 +memberUid: user570 +memberUid: user571 +memberUid: user572 +memberUid: user573 +memberUid: user574 +memberUid: user575 +memberUid: user576 +memberUid: user577 +memberUid: user578 +memberUid: user579 +memberUid: user580 +memberUid: user581 +memberUid: user582 +memberUid: user583 +memberUid: user584 +memberUid: user585 +memberUid: user586 +memberUid: user587 +memberUid: user588 +memberUid: user589 +memberUid: user590 +memberUid: user591 +memberUid: user592 +memberUid: user593 +memberUid: user594 +memberUid: user595 +memberUid: user596 +memberUid: user597 +memberUid: user598 +memberUid: user599 +memberUid: user600 +memberUid: user601 +memberUid: user602 +memberUid: user603 +memberUid: user604 +memberUid: user605 +memberUid: user606 +memberUid: user607 +memberUid: user608 +memberUid: user609 +memberUid: user610 +memberUid: user611 +memberUid: user612 +memberUid: user613 +memberUid: user614 +memberUid: user615 +memberUid: user616 +memberUid: user617 +memberUid: user618 +memberUid: user619 +memberUid: user620 +memberUid: user621 +memberUid: user622 +memberUid: user623 +memberUid: user624 +memberUid: user625 +memberUid: user626 +memberUid: user627 +memberUid: user628 +memberUid: user629 +memberUid: user630 +memberUid: user631 +memberUid: user632 +memberUid: user633 +memberUid: user634 +memberUid: user635 +memberUid: user636 +memberUid: user637 +memberUid: user638 +memberUid: user639 +memberUid: user640 +memberUid: user641 +memberUid: user642 +memberUid: user643 +memberUid: user644 +memberUid: user645 +memberUid: user646 +memberUid: user647 +memberUid: user648 +memberUid: user649 +memberUid: user650 +memberUid: user651 +memberUid: user652 +memberUid: user653 +memberUid: user654 +memberUid: user655 +memberUid: user656 +memberUid: user657 +memberUid: user658 +memberUid: user659 +memberUid: user660 +memberUid: user661 +memberUid: user662 +memberUid: user663 +memberUid: user664 +memberUid: user665 +memberUid: user666 +memberUid: user667 +memberUid: user668 +memberUid: user669 +memberUid: user670 +memberUid: user671 +memberUid: user672 +memberUid: user673 +memberUid: user674 +memberUid: user675 +memberUid: user676 +memberUid: user677 +memberUid: user678 +memberUid: user679 +memberUid: user680 +memberUid: user681 +memberUid: user682 +memberUid: user683 +memberUid: user684 +memberUid: user685 +memberUid: user686 +memberUid: user687 +memberUid: user688 +memberUid: user689 +memberUid: user690 +memberUid: user691 +memberUid: user692 +memberUid: user693 +memberUid: user694 +memberUid: user695 +memberUid: user696 +memberUid: user697 +memberUid: user698 +memberUid: user699 +memberUid: user700 +memberUid: user701 +memberUid: user702 +memberUid: user703 +memberUid: user704 +memberUid: user705 +memberUid: user706 +memberUid: user707 +memberUid: user708 +memberUid: user709 +memberUid: user710 +memberUid: user711 +memberUid: user712 +memberUid: user713 +memberUid: user714 +memberUid: user715 +memberUid: user716 +memberUid: user717 +memberUid: user718 +memberUid: user719 +memberUid: user720 +memberUid: user721 +memberUid: user722 +memberUid: user723 +memberUid: user724 +memberUid: user725 +memberUid: user726 +memberUid: user727 +memberUid: user728 +memberUid: user729 +memberUid: user730 +memberUid: user731 +memberUid: user732 +memberUid: user733 +memberUid: user734 +memberUid: user735 +memberUid: user736 +memberUid: user737 +memberUid: user738 +memberUid: user739 +memberUid: user740 +memberUid: user741 +memberUid: user742 +memberUid: user743 +memberUid: user744 +memberUid: user745 +memberUid: user746 +memberUid: user747 +memberUid: user748 +memberUid: user749 +memberUid: user750 +memberUid: user751 +memberUid: user752 +memberUid: user753 +memberUid: user754 +memberUid: user755 +memberUid: user756 +memberUid: user757 +memberUid: user758 +memberUid: user759 +memberUid: user760 +memberUid: user761 +memberUid: user762 +memberUid: user763 +memberUid: user764 +memberUid: user765 +memberUid: user766 +memberUid: user767 +memberUid: user768 +memberUid: user769 +memberUid: user770 +memberUid: user771 +memberUid: user772 +memberUid: user773 +memberUid: user774 +memberUid: user775 +memberUid: user776 +memberUid: user777 +memberUid: user778 +memberUid: user779 +memberUid: user780 +memberUid: user781 +memberUid: user782 +memberUid: user783 +memberUid: user784 +memberUid: user785 +memberUid: user786 +memberUid: user787 +memberUid: user788 +memberUid: user789 +memberUid: user790 +memberUid: user791 +memberUid: user792 +memberUid: user793 +memberUid: user794 +memberUid: user795 +memberUid: user796 +memberUid: user797 +memberUid: user798 +memberUid: user799 +memberUid: user800 +memberUid: user801 +memberUid: user802 +memberUid: user803 +memberUid: user804 +memberUid: user805 +memberUid: user806 +memberUid: user807 +memberUid: user808 +memberUid: user809 +memberUid: user810 +memberUid: user811 +memberUid: user812 +memberUid: user813 +memberUid: user814 +memberUid: user815 +memberUid: user816 +memberUid: user817 +memberUid: user818 +memberUid: user819 +memberUid: user820 +memberUid: user821 +memberUid: user822 +memberUid: user823 +memberUid: user824 +memberUid: user825 +memberUid: user826 +memberUid: user827 +memberUid: user828 +memberUid: user829 +memberUid: user830 +memberUid: user831 +memberUid: user832 +memberUid: user833 +memberUid: user834 +memberUid: user835 +memberUid: user836 +memberUid: user837 +memberUid: user838 +memberUid: user839 +memberUid: user840 +memberUid: user841 +memberUid: user842 +memberUid: user843 +memberUid: user844 +memberUid: user845 +memberUid: user846 +memberUid: user847 +memberUid: user848 +memberUid: user849 +memberUid: user850 +memberUid: user851 +memberUid: user852 +memberUid: user853 +memberUid: user854 +memberUid: user855 +memberUid: user856 +memberUid: user857 +memberUid: user858 +memberUid: user859 +memberUid: user860 +memberUid: user861 +memberUid: user862 +memberUid: user863 +memberUid: user864 +memberUid: user865 +memberUid: user866 +memberUid: user867 +memberUid: user868 +memberUid: user869 +memberUid: user870 +memberUid: user871 +memberUid: user872 +memberUid: user873 +memberUid: user874 +memberUid: user875 +memberUid: user876 +memberUid: user877 +memberUid: user878 +memberUid: user879 +memberUid: user880 +memberUid: user881 +memberUid: user882 +memberUid: user883 +memberUid: user884 +memberUid: user885 +memberUid: user886 +memberUid: user887 +memberUid: user888 +memberUid: user889 +memberUid: user890 +memberUid: user891 +memberUid: user892 +memberUid: user893 +memberUid: user894 +memberUid: user895 +memberUid: user896 +memberUid: user897 +memberUid: user898 +memberUid: user899 +memberUid: user900 +memberUid: user901 +memberUid: user902 +memberUid: user903 +memberUid: user904 +memberUid: user905 +memberUid: user906 +memberUid: user907 +memberUid: user908 +memberUid: user909 +memberUid: user910 +memberUid: user911 +memberUid: user912 +memberUid: user913 +memberUid: user914 +memberUid: user915 +memberUid: user916 +memberUid: user917 +memberUid: user918 +memberUid: user919 +memberUid: user920 +memberUid: user921 +memberUid: user922 +memberUid: user923 +memberUid: user924 +memberUid: user925 +memberUid: user926 +memberUid: user927 +memberUid: user928 +memberUid: user929 +memberUid: user930 +memberUid: user931 +memberUid: user932 +memberUid: user933 +memberUid: user934 +memberUid: user935 +memberUid: user936 +memberUid: user937 +memberUid: user938 +memberUid: user939 +memberUid: user940 +memberUid: user941 +memberUid: user942 +memberUid: user943 +memberUid: user944 +memberUid: user945 +memberUid: user946 +memberUid: user947 +memberUid: user948 +memberUid: user949 +memberUid: user950 +memberUid: user951 +memberUid: user952 +memberUid: user953 +memberUid: user954 +memberUid: user955 +memberUid: user956 +memberUid: user957 +memberUid: user958 +memberUid: user959 +memberUid: user960 +memberUid: user961 +memberUid: user962 +memberUid: user963 +memberUid: user964 +memberUid: user965 +memberUid: user966 +memberUid: user967 +memberUid: user968 +memberUid: user969 +memberUid: user970 +memberUid: user971 +memberUid: user972 +memberUid: user973 +memberUid: user974 +memberUid: user975 +memberUid: user976 +memberUid: user977 +memberUid: user978 +memberUid: user979 +memberUid: user980 +memberUid: user981 +memberUid: user982 +memberUid: user983 +memberUid: user984 +memberUid: user985 +memberUid: user986 +memberUid: user987 +memberUid: user988 +memberUid: user989 +memberUid: user990 +memberUid: user991 +memberUid: user992 +memberUid: user993 +memberUid: user994 +memberUid: user995 +memberUid: user996 +memberUid: user997 +memberUid: user998 +memberUid: user999 +memberUid: user1000 + +dn: cn=group2,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group2 +gidNumber: 10002 + +dn: cn=group3,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group3 +gidNumber: 10003 + +dn: cn=group4,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group4 +gidNumber: 10004 + +dn: cn=group5,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group5 +gidNumber: 10005 + +dn: cn=group6,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group6 +gidNumber: 10006 + +dn: cn=group7,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group7 +gidNumber: 10007 + +dn: cn=group8,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group8 +gidNumber: 10008 + +dn: cn=group9,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group9 +gidNumber: 10009 + +dn: cn=group10,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group10 +gidNumber: 10010 + +dn: cn=group11,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group11 +gidNumber: 10011 + +dn: cn=group12,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group12 +gidNumber: 10012 + +dn: cn=group13,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group13 +gidNumber: 10013 + +dn: cn=group14,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group14 +gidNumber: 10014 + +dn: cn=group15,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group15 +gidNumber: 10015 + +dn: cn=group16,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group16 +gidNumber: 10016 + +dn: cn=group17,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group17 +gidNumber: 10017 + +dn: cn=group18,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group18 +gidNumber: 10018 + +dn: cn=group19,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group19 +gidNumber: 10019 + +dn: cn=group20,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group20 +gidNumber: 10020 + +dn: cn=group21,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group21 +gidNumber: 10021 + +dn: cn=group22,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group22 +gidNumber: 10022 + +dn: cn=group23,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group23 +gidNumber: 10023 + +dn: cn=group24,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group24 +gidNumber: 10024 + +dn: cn=group25,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group25 +gidNumber: 10025 + +dn: cn=group26,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group26 +gidNumber: 10026 + +dn: cn=group27,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group27 +gidNumber: 10027 + +dn: cn=group28,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group28 +gidNumber: 10028 + +dn: cn=group29,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group29 +gidNumber: 10029 + +dn: cn=group30,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group30 +gidNumber: 10030 + +dn: cn=group31,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group31 +gidNumber: 10031 + +dn: cn=group32,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group32 +gidNumber: 10032 + +dn: cn=group33,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group33 +gidNumber: 10033 + +dn: cn=group34,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group34 +gidNumber: 10034 + +dn: cn=group35,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group35 +gidNumber: 10035 + +dn: cn=group36,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group36 +gidNumber: 10036 + +dn: cn=group37,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group37 +gidNumber: 10037 + +dn: cn=group38,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group38 +gidNumber: 10038 + +dn: cn=group39,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group39 +gidNumber: 10039 + +dn: cn=group40,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group40 +gidNumber: 10040 + +dn: cn=group41,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group41 +gidNumber: 10041 + +dn: cn=group42,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group42 +gidNumber: 10042 + +dn: cn=group43,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group43 +gidNumber: 10043 + +dn: cn=group44,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group44 +gidNumber: 10044 + +dn: cn=group45,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group45 +gidNumber: 10045 + +dn: cn=group46,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group46 +gidNumber: 10046 + +dn: cn=group47,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group47 +gidNumber: 10047 + +dn: cn=group48,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group48 +gidNumber: 10048 + +dn: cn=group49,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group49 +gidNumber: 10049 + +dn: cn=group50,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group50 +gidNumber: 10050 + +dn: cn=group51,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group51 +gidNumber: 10051 + +dn: cn=group52,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group52 +gidNumber: 10052 + +dn: cn=group53,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group53 +gidNumber: 10053 + +dn: cn=group54,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group54 +gidNumber: 10054 + +dn: cn=group55,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group55 +gidNumber: 10055 + +dn: cn=group56,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group56 +gidNumber: 10056 + +dn: cn=group57,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group57 +gidNumber: 10057 + +dn: cn=group58,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group58 +gidNumber: 10058 + +dn: cn=group59,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group59 +gidNumber: 10059 + +dn: cn=group60,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group60 +gidNumber: 10060 + +dn: cn=group61,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group61 +gidNumber: 10061 + +dn: cn=group62,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group62 +gidNumber: 10062 + +dn: cn=group63,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group63 +gidNumber: 10063 + +dn: cn=group64,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group64 +gidNumber: 10064 + +dn: cn=group65,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group65 +gidNumber: 10065 + +dn: cn=group66,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group66 +gidNumber: 10066 + +dn: cn=group67,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group67 +gidNumber: 10067 + +dn: cn=group68,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group68 +gidNumber: 10068 + +dn: cn=group69,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group69 +gidNumber: 10069 + +dn: cn=group70,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group70 +gidNumber: 10070 + +dn: cn=group71,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group71 +gidNumber: 10071 + +dn: cn=group72,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group72 +gidNumber: 10072 + +dn: cn=group73,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group73 +gidNumber: 10073 + +dn: cn=group74,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group74 +gidNumber: 10074 + +dn: cn=group75,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group75 +gidNumber: 10075 + +dn: cn=group76,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group76 +gidNumber: 10076 + +dn: cn=group77,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group77 +gidNumber: 10077 + +dn: cn=group78,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group78 +gidNumber: 10078 + +dn: cn=group79,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group79 +gidNumber: 10079 + +dn: cn=group80,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group80 +gidNumber: 10080 + +dn: cn=group81,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group81 +gidNumber: 10081 + +dn: cn=group82,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group82 +gidNumber: 10082 + +dn: cn=group83,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group83 +gidNumber: 10083 + +dn: cn=group84,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group84 +gidNumber: 10084 + +dn: cn=group85,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group85 +gidNumber: 10085 + +dn: cn=group86,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group86 +gidNumber: 10086 + +dn: cn=group87,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group87 +gidNumber: 10087 + +dn: cn=group88,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group88 +gidNumber: 10088 + +dn: cn=group89,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group89 +gidNumber: 10089 + +dn: cn=group90,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group90 +gidNumber: 10090 + +dn: cn=group91,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group91 +gidNumber: 10091 + +dn: cn=group92,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group92 +gidNumber: 10092 + +dn: cn=group93,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group93 +gidNumber: 10093 + +dn: cn=group94,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group94 +gidNumber: 10094 + +dn: cn=group95,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group95 +gidNumber: 10095 + +dn: cn=group96,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group96 +gidNumber: 10096 + +dn: cn=group97,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group97 +gidNumber: 10097 + +dn: cn=group98,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group98 +gidNumber: 10098 + +dn: cn=group99,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group99 +gidNumber: 10099 + +dn: cn=group100,dc=example,dc=org +objectClass: top +objectClass: posixGroup +cn: group100 +gidNumber: 10100 + diff --git a/demos/ldap-integration/policy/01_root.yml b/demos/ldap-integration/policy/01_root.yml new file mode 100644 index 00000000..caf56ecf --- /dev/null +++ b/demos/ldap-integration/policy/01_root.yml @@ -0,0 +1,2 @@ +- !policy conjur/ldap-sync +- !policy conjur/authn-ldap diff --git a/demos/ldap-integration/policy/02_ldap_sync.yml b/demos/ldap-integration/policy/02_ldap_sync.yml new file mode 100644 index 00000000..0cf457ab --- /dev/null +++ b/demos/ldap-integration/policy/02_ldap_sync.yml @@ -0,0 +1,33 @@ +- !host +- !webservice + owner: !host +- !group + owner: !host + +- !resource + id: default + owner: !host + kind: configuration + annotations: + ldap-sync/base_dn: dc=example,dc=org + ldap-sync/bind_dn: cn=admin,dc=example,dc=org + ldap-sync/connect_type: tls + ldap-sync/host: ldap-server + ldap-sync/port: 389 + ldap-sync/group_attribute_mapping/name: cn + ldap-sync/user_attribute_mapping/name: uid + ldap-sync/group_attribute_mapping/gid: gidNumber + ldap-sync/user_attribute_mapping/uid: uidNumber + ldap-sync/group_filter: (objectClass=posixGroup) + ldap-sync/user_filter: (objectClass=person) + ldap-sync/import_gid_numbers: true + ldap-sync/import_public_keys: false + ldap-sync/import_uid_numbers: true + +- !variable + id: bind-password/default + owner: !host + +- !variable + id: tls-ca-cert/default + owner: !host diff --git a/demos/ldap-integration/policy/03_authn_ldap.yml b/demos/ldap-integration/policy/03_authn_ldap.yml new file mode 100644 index 00000000..d5a0a287 --- /dev/null +++ b/demos/ldap-integration/policy/03_authn_ldap.yml @@ -0,0 +1,28 @@ +- !policy + id: ldap-server + body: + - !host + - !webservice + owner: !host + annotations: + ldap-authn/base_dn: dc=example,dc=org + ldap-authn/bind_dn: cn=admin,dc=example,dc=org + ldap-authn/connect_type: tls + ldap-authn/host: ldap-server + ldap-authn/port: 389 + ldap-authn/filter_template: (&(objectClass=person)(uid=%s)) + + - !group clients + + - !permit + role: !group clients + privilege: [ read, authenticate ] + resource: !webservice + + - !variable + id: bind-password + owner: !host + + - !variable + id: tls-ca-cert + owner: !host diff --git a/demos/ldap-integration/policy/04_authn_ldap_entitlements.yml b/demos/ldap-integration/policy/04_authn_ldap_entitlements.yml new file mode 100644 index 00000000..9b7616cc --- /dev/null +++ b/demos/ldap-integration/policy/04_authn_ldap_entitlements.yml @@ -0,0 +1,3 @@ +- !grant + role: !group conjur/authn-ldap/ldap-server/clients + member: !group All Users diff --git a/demos/ldap-integration/start b/demos/ldap-integration/start new file mode 100755 index 00000000..9e8f2b7b --- /dev/null +++ b/demos/ldap-integration/start @@ -0,0 +1,82 @@ +#!/bin/bash -ex + +function print_help() { + cat << EOF + +Provisions a Conjur cluster locally, using Docker. + +Usage: start [options] + + -h, --help Shows this help message. + +EOF + exit +} + +while true ; do + case "$1" in + -h | --help ) print_help ; shift ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac +done + +docker-compose up -d --no-deps conjur-master.mycompany.local conjur-follower.mycompany.local ldap-server + +docker-compose exec conjur-master.mycompany.local bash -c " + evoke configure master \ + --accept-eula \ + -h conjur-master.mycompany.local \ + -p secret demo +" + +master_container="$(docker ps -q --filter "name=ldap-integration_conjur-master.mycompany.local_1")" +master_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $master_container) + +docker-compose exec conjur-master.mycompany.local bash -c " + evoke seed follower conjur-follower.mycompany.local > /opt/conjur/backup/follower-seed.tar +" + +# Enable LDAP sync service +docker-compose exec conjur-master.mycompany.local bash -c " + rm /etc/service/conjur/ldap-sync/down + sv start conjur/ldap-sync +" + +# Setup the follower +docker-compose exec conjur-follower.mycompany.local bash -c " + evoke unpack seed /opt/conjur/backup/follower-seed.tar +" +docker-compose exec conjur-follower.mycompany.local bash -c " + evoke configure follower +" + +# Load the LDAP users and groups into OpenLDAP +LDAP_ADMIN_PASSWORD=ldapsecret +docker-compose exec ldap-server bash -c " + ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f /opt/ldap/disable_anon_frontend.ldif + ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f /opt/ldap//disable_anon_backend.ldif + ldapadd -Z -x -D cn=admin,dc=example,dc=org -w $LDAP_ADMIN_PASSWORD -f /opt/ldap/test-ldap_users.ldif + ldapadd -Z -x -D cn=admin,dc=example,dc=org -w $LDAP_ADMIN_PASSWORD -f /opt/ldap//test-ldap_groups.ldif + " + +./cli conjur policy load --replace root policy/01_root.yml + +# Load policy for LDAP sync +./cli conjur policy load conjur/ldap-sync policy/02_ldap_sync.yml + +# Store the LDAP bind password +./cli conjur variable values add conjur/ldap-sync/bind-password/default $LDAP_ADMIN_PASSWORD + +cat certs/ca.crt | ./cli conjur variable values add conjur/ldap-sync/tls-ca-cert/default + +# Generate sync policy +./cli conjur ldap-sync policy show | tail -n +2 > ./policy/ldap-sync-default.yml +./cli conjur policy load root policy/ldap-sync-default.yml + +# Load policy for authn LDAP +./cli conjur policy load conjur/authn-ldap policy/03_authn_ldap.yml +./cli conjur policy load root policy/04_authn_ldap_entitlements.yml + +# Store the LDAP bind password and CA cert chain +./cli conjur variable values add conjur/authn-ldap/ldap-server/bind-password $LDAP_ADMIN_PASSWORD +cat certs/ca.crt | ./cli conjur variable values add conjur/authn-ldap/ldap-server/tls-ca-cert diff --git a/demos/ldap-integration/stop b/demos/ldap-integration/stop new file mode 100755 index 00000000..dee00c52 --- /dev/null +++ b/demos/ldap-integration/stop @@ -0,0 +1,6 @@ +#!/bin/bash -ex + +docker-compose down -v + +rm -rf cli_cache +rm -f ./policy/ldap-sync*.yml diff --git a/demos/openshift-install/README.md b/demos/openshift-install/README.md new file mode 100644 index 00000000..6cffec17 --- /dev/null +++ b/demos/openshift-install/README.md @@ -0,0 +1,94 @@ +# Conjur Installation Demo on OpenShift + +## Explanations + +The purpose of this demo is to install Conjur on existing OpenShift environment and then run Java Client on top of it +The environent contains 4 pods each with up to 2 containers inside +Pod #1: Postgres +Pod #2: Conjur + Nginx +Pod #3: Conjur CLI +Pod #4: Conjur authenticator client + Java Client + +## Local Prerequisites + +Git - git version 2.24.1 +Maven - Apache Maven 3.6.3 +Java SDK / JRE - openjdk version "1.8.0_232" +macOS Catalina - Version 10.15.1 (19076) +OpenShift client installed on you local station + +## External Prerequisites + +A GitHub user for GitHub environment +OpenShift - oc v3.11.0+0cbc58b + kubernetes v1.11.0+d4cacc0 + features: Basic-Auth + +## Important Note: +The commands below can run in either an interactive mode as well as in a command line mode. +Interactive mode means that each parameter that was not filled in the command line will be asked to be provided interactively. +In interactive mode, some of these parameters have default values defined. +If the user does not provide an input, the default value is taken. + +## Commands + +1. Building the Java Client: + +```bash +$ cd /conjur-intro/demos/java-api-client +$ ./build.sh +``` + +2. Installing and running ia demo Java client in OpenShift: + +```bash +$ ./java-client-installer.sh --ocp-url --docker-url --project-name --account-name --authenticator +``` + +| Flag | Meaning | +| ---- | ------- | +|`--ocp-url` | Sets the OpenShift cluster in which the demo Java client would be installed (should have the same value as above) | +|`--docker-url` | Sets the Docker registry into which the container image of the demo Java client would be pushed | +|`--project-name` | Sets the OpenShift project in which the demo Java client would be installed (should have the same value as above) | +|`--account-name` | Sets the Conjur account that would be used by the demo Java client (should have the same value as above) | +|`--authenticator` | Sets the authenticator name that would be used by the demo Java client (should have the same value as above) | + +3. Verify that all pods are up and running by: + +```bash +$ oc get pods +``` + +4. Checking output of the demo Java client container in pod #4: + +```bash +$ oc logs -c my-conjur-java-client +``` + + It should show that the secret was retrieved properly. + +## Remark: +There is an option to run installer.sh script to install Conjur + Conjur CLI and (optionally) load configuration to it. +Commands for it are: + +1. Installing Conjur and Conjur CLI in OpenShift: + +```bash +$ cd /conjur-intro/demos/openshift-install +$ ./installer.sh --ocp-url --project-name --account-name --authenticator +``` + +| Flag | Meaning | +| ---- | ------- | +|`--ocp-url` | Sets the OpenShift cluster in which Conjur would be installed | +|`--project-name` | Sets the OpenShift project in which Conjur be installed| +|`--account-name` | Sets the Conjur account that would be created| +|`--authenticator` | Sets the authenticator name that would be created| + +2. Verify that all pods are up and running by: + +```bash +$ oc get pods +``` + + diff --git a/demos/openshift-install/cleanup.sh b/demos/openshift-install/cleanup.sh new file mode 100755 index 00000000..8829175b --- /dev/null +++ b/demos/openshift-install/cleanup.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +#set -x +#set -e + +function validate_app { + APPNAME=$1 + CHECK_APP=$( which $APPNAME ) + if [ -z "$CHECK_APP" ] + then + echo "Please install $APPNAME" + exit 1 + fi +} + +validate_app oc + +oc delete project $1 diff --git a/demos/openshift-install/conjur-cli.yaml b/demos/openshift-install/conjur-cli.yaml new file mode 100644 index 00000000..7897361d --- /dev/null +++ b/demos/openshift-install/conjur-cli.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: conjur-cli + labels: + app: conjur-cli +spec: + replicas: 1 + selector: + matchLabels: + app: conjur-cli + template: + metadata: + name: conjur-cli + labels: + app: conjur-cli + spec: + serviceAccountName: default + containers: + - name: conjur-cli + image: cyberark/conjur-cli:5-latest + imagePullPolicy: IfNotPresent + command: ["sleep"] + args: ["infinity"] + imagePullSecrets: + - name: dockerpullsecret diff --git a/demos/openshift-install/conjur_scripts/cert_script.sh b/demos/openshift-install/conjur_scripts/cert_script.sh new file mode 100755 index 00000000..8238e53e --- /dev/null +++ b/demos/openshift-install/conjur_scripts/cert_script.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e +AUTHENTICATOR_ID=$2 +CONJUR_ACCOUNT=$1 + +# Generate OpenSSL private key +openssl genrsa -out ca.key 2048 + +CONFIG=" +[ req ] +distinguished_name = dn +x509_extensions = v3_ca +[ dn ] +[ v3_ca ] +basicConstraints = critical,CA:TRUE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +" + +# Generate root CA certificate +openssl req -x509 -new -nodes -key ca.key -sha1 -days 3650 -set_serial 0x0 -out ca.cert \ + -subj "/CN=conjur.authn-k8s.$AUTHENTICATOR_ID/OU=Conjur Kubernetes CA/O=$CONJUR_ACCOUNT" \ + -config <(echo "$CONFIG") + +# Verify cert +openssl x509 -in ca.cert -text -noout &> /dev/null + +# Load variable values +conjur variable values add conjur/authn-k8s/$AUTHENTICATOR_ID/ca/key "$(cat ca.key)" +conjur variable values add conjur/authn-k8s/$AUTHENTICATOR_ID/ca/cert "$(cat ca.cert)" + diff --git a/demos/openshift-install/docker-compose.yml b/demos/openshift-install/docker-compose.yml new file mode 100755 index 00000000..f2f74369 --- /dev/null +++ b/demos/openshift-install/docker-compose.yml @@ -0,0 +1,16 @@ +version: '2' +services: + + database: + image: postgres:9.4 + container_name: postgres_database + + conjur: + image: cyberark/conjur + container_name: conjur_server + command: server + environment: + DATABASE_URL: postgres://postgres@database/postgres + CONJUR_DATA_KEY: + depends_on: [ database ] + diff --git a/demos/openshift-install/installer.sh b/demos/openshift-install/installer.sh new file mode 100755 index 00000000..f2c4f088 --- /dev/null +++ b/demos/openshift-install/installer.sh @@ -0,0 +1,216 @@ +#!/bin/bash + +#set -x +set -e + +OPENSHIFT_URL= +PROJECT_NAME= +ACCOUNT_NAME= +AUTHENTICATOR= + +function validate_app { + APPNAME=$1 + CHECK_APP=$( which $APPNAME ) + if [ -z "$CHECK_APP" ] + then + echo "Please install $APPNAME" + exit 1 + fi +} + +function prepare_input { + + local PARAM_VALUE=$1 + local PARAM_NAME=$2 + local DEFAULT_VALUE=$3 + + if [ "$PARAM_VALUE" == "" ]; then + if [ -n "$DEFAULT_VALUE" ]; then + read -p "Please specify the $PARAM_NAME [$DEFAULT_VALUE]:" PARAM_VALUE + else + read -p "Please specify the $PARAM_NAME:" PARAM_VALUE + fi + if [ "$PARAM_VALUE" == "" ]; then + if [ -n "$DEFAULT_VALUE" ]; then + PARAM_VALUE=$DEFAULT_VALUE + else + echo "Missing value in $PARAM_NAME - exiting" + exit 1 + fi + fi + fi + + echo "$PARAM_VALUE" + +} + +function validate { + validate_app helm + validate_app oc + validate_app docker + validate_app docker-compose + validate_app awk + validate_app openssl + validate_app keytool +} + +function install { + + oc login $OPENSHIFT_URL + #oc adm prune images + echo "Creating project $PROJECT_NAME" + + oc new-project $PROJECT_NAME + + TOKEN=$( oc whoami -t ) + + DATA_KEY=$( docker-compose run --no-deps --rm conjur data-key generate ) + + oc get is + echo "Installing Conjur OSS application on OpenShift" + oc delete ClusterRole conjur-oss-conjur-authenticator --ignore-not-found + oc delete ClusterRoleBinding conjur-oss-conjur-authenticator --ignore-not-found + + + cat templates/custom-values.yaml | sed s/'{{ AUTHENTICATOR }}'/$AUTHENTICATOR/g | sed s/'{{ ACCOUNT_NAME }}'/$ACCOUNT_NAME/g > custom-values.yaml.tmp + + cat custom-values.yaml.tmp | awk "{gsub(/{{ DATA_KEY }}/,\"$DATA_KEY\")}1" > custom-values.yaml + rm -rf custom-values.yaml.tmp + ##cat custom-values.yaml + echo "Installing conjur-oss" + oc adm policy add-scc-to-user anyuid "system:serviceaccount:$PROJECT_NAME:default" &> /dev/null + helm install conjur-oss -f custom-values.yaml https://github.com/cyberark/conjur-oss-helm-chart/releases/download/v1.3.8/conjur-oss-1.3.8.tgz &> /dev/null + echo "Installation done" + oc adm policy add-scc-to-user anyuid "system:serviceaccount:$PROJECT_NAME:default" &> /dev/null + + CONJUR_OSS_POD_LINE=$( oc get pods | grep conjur-oss | (head -n1 && tail -n1) ) + + CONJUR_OSS_POD=$( echo "$CONJUR_OSS_POD_LINE" | awk '{print $1}' ) + + for i in {1..50} + do + CONTAINERS_STATUS=$( oc get pods | grep conjur-oss | (head -n1 && tail -n1) | awk '{print $2}' ) + + if [ "$CONTAINERS_STATUS" == "2/2" ]; then + break + fi + echo "Waiting for conjur pod to be up..." + sleep 2 + done + + oc get pods + + if [ "$CONTAINERS_STATUS" != "2/2" ]; then + echo "Conjur pod did not come up properly - exiting" + exit 1 + fi + + echo "Create account" + CONJUR_OUTPUT_INIT=$( oc exec "$CONJUR_OSS_POD" --container=conjur-oss conjurctl account create $ACCOUNT_NAME ) + API_KEY=$( echo "$CONJUR_OUTPUT_INIT" | grep "API key" | awk '{print $5}' ) + echo "Create CLI pod" + oc create -f conjur-cli.yaml + +} + +function config { + + echo "Creating basic configuration to Conjur" + CONJUR_CLI_POD=$( oc get pods | grep conjur-cli | (head -n1 && tail -n1) | cut -f 1 -d " " ) + + mkdir -p policy + + echo -e "admin\n$API_KEY" > policy/authnInput + + cat templates/policy-hosts-to-authenticate.yaml | sed s/'{{ AUTHENTICATOR }}'/$AUTHENTICATOR/g | sed s/'{{ PROJECT_NAME }}'/$PROJECT_NAME/g > policy/policy-hosts-to-authenticate.yaml + + cat templates/policy-for-webservice.yaml | sed s/'{{ AUTHENTICATOR }}'/$AUTHENTICATOR/g > policy/policy-for-webservice.yaml + + cat templates/policy-for-variables.yaml | sed s/'{{ AUTHENTICATOR }}'/$AUTHENTICATOR/g | sed s/'{{ PROJECT_NAME }}'/$PROJECT_NAME/g > policy/policy-for-variables.yaml + + echo "Load conjur policy" + + oc rsync policy "$CONJUR_CLI_POD":/ + oc rsync conjur_scripts "$CONJUR_CLI_POD":/ + + oc exec -it "$CONJUR_CLI_POD" conjur init <<< "https://conjur-oss +yes +$ACCOUNT_NAME +y +" + oc exec -it "$CONJUR_CLI_POD" conjur authn login < policy/authnInput + + oc exec -it "$CONJUR_CLI_POD" conjur policy load root policy/policy-hosts-to-authenticate.yaml + oc exec -it "$CONJUR_CLI_POD" conjur policy load root policy/policy-for-webservice.yaml + oc exec -it "$CONJUR_CLI_POD" conjur policy load root policy/policy-for-variables.yaml + oc exec -it "$CONJUR_CLI_POD" conjur variable values add variables/mypassword 123 + + echo "Create certificate" + oc exec -it "$CONJUR_CLI_POD" ./conjur_scripts/cert_script.sh $ACCOUNT_NAME $AUTHENTICATOR + oc exec -it "$CONJUR_CLI_POD" cat /root/conjur-$ACCOUNT_NAME.pem > conjur-cert.pem + oc delete --ignore-not-found=true configmap conjur-cert + ssl_certificate=$(cat conjur-cert.pem ) + oc create configmap conjur-cert --from-literal=ssl-certificate="$ssl_certificate" + + oc delete --ignore-not-found=true configmap conjur-cert-java + oc create configmap conjur-cert-java --from-file=ssl-certificate=conjur-cert.pem +} + +usage() +{ + cat << EOF + + Installs Conjur with Conjut CLI on OpenShift + + Usage: installer.sh [options] + + -h, --help Shows this help message + --ocp-url OpenShift URL (mandatory) + --project-name OpenShift project name (mandatory) + --account-name Conjur account name (mandatory) + --authenticator Conjur authenticator (mandatory) +EOF +} + +while [ "$1" != "" ]; do + case $1 in + --ocp-url ) shift + OPENSHIFT_URL=$1 + ;; + --project-name ) shift + PROJECT_NAME=$1 + ;; + --account-name ) shift + ACCOUNT_NAME=$1 + ;; + --authenticator ) shift + AUTHENTICATOR=$1 + ;; + -h | --help ) usage + exit + ;; + * ) usage + exit 1 + esac + shift +done + +validate + +OPENSHIFT_URL=$(prepare_input "$OPENSHIFT_URL" "OpenShift URL") +PROJECT_NAME=$(prepare_input "$PROJECT_NAME" "project name") +ACCOUNT_NAME=$(prepare_input "$ACCOUNT_NAME" "account name" "default") +AUTHENTICATOR=$(prepare_input "$AUTHENTICATOR" "authenticator") + +install + +config + +#rm -rf conjur-cert.crt +#rm -rf conjur-cert.pem +rm -rf custom-values.yaml +rm -rf policy + +echo "Installation done" + + diff --git a/demos/openshift-install/java-client-installer.sh b/demos/openshift-install/java-client-installer.sh new file mode 100755 index 00000000..382c11cf --- /dev/null +++ b/demos/openshift-install/java-client-installer.sh @@ -0,0 +1,161 @@ +#!/bin/bash + +#set -x +set -e + +OPENSHIFT_URL= +PROJECT_NAME= +ACCOUNT_NAME= +AUTHENTICATOR= +DEPLOYMENT_NAME=conjur-java-api-example + +function validate_app { + APPNAME=$1 + CHECK_APP=$( which $APPNAME ) + if [ -z "$CHECK_APP" ] + then + echo "Please install $APPNAME" + exit 1 + fi +} + +function validate { + validate_app helm + validate_app oc + validate_app docker + validate_app docker-compose + validate_app awk + validate_app openssl + validate_app keytool +} + +function prepare_input { + + local PARAM_VALUE=$1 + local PARAM_NAME=$2 + local DEFAULT_VALUE=$3 + + if [ "$PARAM_VALUE" == "" ]; then + if [ -n "$DEFAULT_VALUE" ]; then + read -p "Please specify the $PARAM_NAME [$DEFAULT_VALUE]:" PARAM_VALUE + else + read -p "Please specify the $PARAM_NAME:" PARAM_VALUE + fi + if [ "$PARAM_VALUE" == "" ]; then + if [ -n "$DEFAULT_VALUE" ]; then + PARAM_VALUE=$DEFAULT_VALUE + else + echo "Missing value in $PARAM_NAME - exiting" + exit 1 + fi + fi + fi + + echo "$PARAM_VALUE" + +} + + +function install { + + echo "entering project $PROJECT_NAME" + oc project $PROJECT_NAME + + echo "Pods originally running:" + oc get pods + + TOKEN=$( oc whoami -t ) + + echo "Pushing java client docker image to openshift" + docker tag conjur-java-client:latest $DOCKER_URL/$PROJECT_NAME/conjur-java-client:latest + docker login $DOCKER_URL -u _ -p $TOKEN + docker push $DOCKER_URL/$PROJECT_NAME/conjur-java-client:latest + + oc get is + + echo "Running Conjur Java Client in OpenShift" + cat templates/conjur-java-api-example.yaml | sed s/'{{ AUTHENTICATOR }}'/$AUTHENTICATOR/g | sed s/'{{ ACCOUNT_NAME }}'/$ACCOUNT_NAME/g | sed s/'{{ DEPLOYMENT_NAME }}'/$DEPLOYMENT_NAME/g | sed s/'{{ PROJECT_NAME }}'/$PROJECT_NAME/g > conjur-java-api-example.yaml + oc create -f conjur-java-api-example.yaml + +} + +usage() +{ + echo "usage: installer [[[--ocp-url url ] [--docker-url url ] [--project-name project] [--account-name account] [--authenticator authenticator]] | [-h]]" + +cat << EOF + + Installs Conjur with Conjut CLI on OpenShift + + Usage: installer.sh [options] + + -h, --help Shows this help message + --ocp-url OpenShift URL (mandatory) + --docker-url Docker URL (mandatory) + --project-name OpenShift project name (mandatory) + --account-name Conjur account name (mandatory) + --authenticator Conjur authenticator (mandatory) +EOF +} + +DO_CONFIG=0 +while [ "$1" != "" ]; do + case $1 in + --ocp-url ) shift + OPENSHIFT_URL=$1 + ;; + --docker-url ) shift + DOCKER_URL=$1 + ;; + --project-name ) shift + PROJECT_NAME=$1 + ;; + --account-name ) shift + ACCOUNT_NAME=$1 + ;; + --authenticator ) shift + AUTHENTICATOR=$1 + ;; + -h | --help ) usage + exit + ;; + * ) usage + exit 1 + esac + shift +done + +validate + +OPENSHIFT_URL=$(prepare_input "$OPENSHIFT_URL" "OpenShift URL") +DOCKER_URL=$(prepare_input "$DOCKER_URL" "OpenShift Docker registry URL") +PROJECT_NAME=$(prepare_input "$PROJECT_NAME" "project name") +ACCOUNT_NAME=$(prepare_input "$ACCOUNT_NAME" "account name" "default") +AUTHENTICATOR=$(prepare_input "$AUTHENTICATOR" "authenticator") + +./installer.sh --ocp-url "$OPENSHIFT_URL" --project-name "$PROJECT_NAME" --account-name "$ACCOUNT_NAME" --authenticator "$AUTHENTICATOR" + +install + +CONJUR_JAVA_API_POD_LINE=$( oc get pods | grep conjur-java-api-example | (head -n1 && tail -n1) ) + +CONJUR_JAVA_API_POD=$( echo "$CONJUR_JAVA_API_POD_LINE" | awk '{print $1}' ) + +for i in {1..50} +do + CONTAINERS_STATUS=$( oc get pods | grep conjur-java-api-example | (head -n1 && tail -n1) | awk '{print $2}' ) + + if [ "$CONTAINERS_STATUS" == "2/2" ]; then + break + fi + echo "Waiting for the Java client pod to start..." + sleep 2 +done + +oc get pods + +rm -rf conjur-java-api-example.yaml + +echo "Installation done" + +oc logs $CONJUR_JAVA_API_POD -c my-conjur-java-client diff --git a/demos/openshift-install/templates/conjur-java-api-example.yaml b/demos/openshift-install/templates/conjur-java-api-example.yaml new file mode 100644 index 00000000..0d2f9fe8 --- /dev/null +++ b/demos/openshift-install/templates/conjur-java-api-example.yaml @@ -0,0 +1,98 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ DEPLOYMENT_NAME }} + labels: + app: {{ DEPLOYMENT_NAME }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ DEPLOYMENT_NAME }} + template: + metadata: + name: {{ DEPLOYMENT_NAME }} + labels: + app: {{ DEPLOYMENT_NAME }} + spec: + serviceAccountName: default + containers: + - image: cyberark/conjur-kubernetes-authenticator:latest + imagePullPolicy: IfNotPresent + name: authenticator + env: + - name: CONJUR_VERSION + value: "5" + - name: CONTAINER_MODE + value: sidecar + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CONJUR_AUTHN_URL + value: https://conjur-oss.{{ PROJECT_NAME }}.svc.cluster.local/authn-k8s/{{ AUTHENTICATOR }} + - name: CONJUR_APPLIANCE_URL + value: https://conjur-oss.{{ PROJECT_NAME }}.svc.cluster.local + - name: CONJUR_ACCOUNT + value: {{ ACCOUNT_NAME }} + - name: CONJUR_AUTHN_LOGIN + value: "host/conjur/authn-k8s/{{ AUTHENTICATOR }}/apps/{{ PROJECT_NAME }}/*/*" + - name: CONJUR_SSL_CERTIFICATE + valueFrom: + configMapKeyRef: + name: conjur-cert + key: ssl-certificate + volumeMounts: + - mountPath: /run/conjur + name: conjur-access-token + - name: my-conjur-java-client + image: docker-registry.default.svc:5000/{{ PROJECT_NAME }}/conjur-java-client:latest + imagePullPolicy: Always + env: + - name: CONJUR_AUTHN_URL + value: https://conjur-oss.{{ PROJECT_NAME }}.svc.cluster.local/authn-k8s/{{ AUTHENTICATOR }} + - name: CONJUR_APPLIANCE_URL + value: https://conjur-oss.{{ PROJECT_NAME }}.svc.cluster.local + - name: CONJUR_ACCOUNT + value: {{ ACCOUNT_NAME }} + - name: CONJUR_AUTHN_TOKEN_FILE + value: /run/conjur/access-token + - name: CONJUR_SSL_CERTIFICATE + valueFrom: + configMapKeyRef: + name: conjur-cert + key: ssl-certificate + volumeMounts: + - mountPath: /run/conjur + name: conjur-access-token + initContainers: + - name: pem-to-truststore + image: registry.access.redhat.com/redhat-sso-7/sso71-openshift:1.1-16 + env: + - name: CONJUR_SSL_CERTIFICATE + valueFrom: + configMapKeyRef: + name: conjur-cert-java + key: ssl-certificate + - name: truststore_jks + value: /run/conjur/truststore.jks + - name: password + value: changeit + command: ['/bin/bash'] + args: ['-c', "echo \"$CONJUR_SSL_CERTIFICATE\" > conjur-cert.pem && openssl x509 -outform der -in conjur-cert.pem -out conjur-cert.crt && echo \"Creating TrustStore file in /run/conjur/truststore.jks\" && keytool -import -noprompt -keystore $truststore_jks -file conjur-cert.crt -storepass changeit -alias ca "] + volumeMounts: + - mountPath: /run/conjur + name: conjur-access-token + volumes: + - name: conjur-access-token + emptyDir: + medium: Memory diff --git a/demos/openshift-install/templates/custom-values.yaml b/demos/openshift-install/templates/custom-values.yaml new file mode 100644 index 00000000..41bb4883 --- /dev/null +++ b/demos/openshift-install/templates/custom-values.yaml @@ -0,0 +1,15 @@ +authenticators: "authn-k8s/{{ AUTHENTICATOR }},authn" +dataKey: "{{ DATA_KEY }}" +account: "{{ ACCOUNT_NAME }}" + +image: + repository: "cyberark/conjur" + tag: "latest" + pullPolicy: Always + +ssl: + hostname: custom.domainname.com + +postgres: + persistentVolume: + create: false diff --git a/demos/openshift-install/templates/policy-for-variables.yaml b/demos/openshift-install/templates/policy-for-variables.yaml new file mode 100644 index 00000000..7cc1d6bc --- /dev/null +++ b/demos/openshift-install/templates/policy-for-variables.yaml @@ -0,0 +1,12 @@ +--- +# This policy defines an authn-k8s endpoint, CA creds and a layer for whitelisted identities permitted to authenticate to it +- !policy + id: variables + body: + - !variable + id: mypassword + + - !permit + resource: !variable mypassword + privilege: [ read, execute ] + role: !host /conjur/authn-k8s/{{ AUTHENTICATOR }}/apps/{{ PROJECT_NAME }}/*/* diff --git a/demos/openshift-install/templates/policy-for-webservice.yaml b/demos/openshift-install/templates/policy-for-webservice.yaml new file mode 100644 index 00000000..4df09d2a --- /dev/null +++ b/demos/openshift-install/templates/policy-for-webservice.yaml @@ -0,0 +1,30 @@ +# This policy defines an authn-k8s endpoint, CA creds and a layer for whitelisted identities permitted to authenticate to it +- !policy + id: conjur/authn-k8s/{{ AUTHENTICATOR }} + owner: !group devops + annotations: + description: Namespace defs for the Conjur cluster in dev + body: + - !webservice + annotations: + description: authn service for cluster + +# CA cert and key for creating client certificates + - !policy + id: ca + body: + - !variable + id: cert + annotations: + description: CA cert for Kubernetes Pods. + - !variable + id: key + annotations: + description: CA key for Kubernetes Pods. + + # permit a layer of whitelisted authn ids to call authn service + - !permit + resource: !webservice + privilege: [ read, authenticate ] + role: !layer /conjur/authn-k8s/{{ AUTHENTICATOR }}/apps + diff --git a/demos/openshift-install/templates/policy-hosts-to-authenticate.yaml b/demos/openshift-install/templates/policy-hosts-to-authenticate.yaml new file mode 100644 index 00000000..8e399678 --- /dev/null +++ b/demos/openshift-install/templates/policy-hosts-to-authenticate.yaml @@ -0,0 +1,22 @@ +--- +# This policy defines a layer of whitelisted identities permitted to authenticate to the authn-k8s endpoint. +- !group devops +- !policy + id: conjur/authn-k8s/{{ AUTHENTICATOR }}/apps + owner: !group devops + annotations: + description: Identities permitted to authenticate + body: + - !layer + annotations: + description: Layer of authenticator identities permitted to call authn svc + - &hosts + - !host + id: {{ PROJECT_NAME }}/*/* + annotations: + kubernetes/authentication-container-name: authenticator + openshift: "true" + + - !grant + role: !layer + members: *hosts diff --git a/demos/pet-store/docker-compose.yml b/demos/pet-store/docker-compose.yml new file mode 100644 index 00000000..dc142b21 --- /dev/null +++ b/demos/pet-store/docker-compose.yml @@ -0,0 +1,29 @@ +version: "3" +services: + pet-store: + image: jvanderhoof/test-app:0.0.1 + environment: + DB_URL: postgres://postgres@pg/postgres + DB_USERNAME: postgres + DB_PASSWORD: secret + volumes: + - ./secrets.yml:/secrets/secrets.yml + pg: + image: postgres:9.4 + environment: + POSTGRES_PASSWORD: secret + + + + # client: + # image: conjurinc/cli5 + # working_dir: -w /src/cli + # environment: + # CONJUR_APPLIANCE_URL: https://conjur + # CONJUR_ACCOUNT: demo + # CONJUR_AUTHN_LOGIN: admin + # links: + # - conjur:conjur + # volumes: + # - .:/src/cli + # - ./cli_cache:/root diff --git a/demos/pet-store/secrets.yml b/demos/pet-store/secrets.yml new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..92d64507 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,216 @@ +version: "3" +services: + conjur-master.mycompany.local: + image: haproxy:2.1-alpine + networks: + dap_net: + ipv4_address: 12.16.23.10 + ports: + - "443:443" + - "7000:7000" + expose: + - "1999" + - "5432" + volumes: + - master-certs:/etc/ssl/certs + - ./files/haproxy/master:/usr/local/etc/haproxy + + conjur-master-1.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + networks: + dap_net: + ipv4_address: 12.16.23.11 + ports: + - "444:443" + expose: + - "443" + - "444" + - "1999" + - "5432" + environment: + TRUSTED_PROXIES: 123.123.1.1,123.5.1.1 + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - master-certs:/opt/conjur/etc/ssl/ + - ./system/backup:/opt/conjur/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs/master-1:/var/log/conjur:Z + - ./files:/conjur_files + - ./files/dhparam.pem:${DHPATH}/dhparam.pem + + conjur-master-2.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + networks: + dap_net: + ipv4_address: 12.16.23.12 + ports: + - "445:443" + expose: + - "443" + - "444" + - "1999" + - "5432" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - master-certs:/opt/conjur/etc/ssl/ + - ./system/backup:/opt/conjur/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs/master-2:/var/log/conjur:Z + - ./files:/conjur_files + + conjur-master-3.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + networks: + dap_net: + ipv4_address: 12.16.23.13 + ports: + - "446:443" + expose: + - "443" + - "444" + - "1999" + - "5432" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - master-certs:/opt/conjur/etc/ssl/ + - ./system/backup:/opt/conjur/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs/master-3:/var/log/conjur:Z + - ./files:/conjur_files + + conjur-master-4.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + networks: + dap_net: + ipv4_address: 12.16.23.14 + ports: + - "447:443" + expose: + - "443" + - "444" + - "1999" + - "5432" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - master-certs:/opt/conjur/etc/ssl/ + - ./system/backup:/opt/conjur/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs/master-4:/var/log/conjur:Z + - ./files:/conjur_files + + conjur-master-5.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + networks: + dap_net: + ipv4_address: 12.16.23.15 + ports: + - "448:443" + expose: + - "443" + - "444" + - "1999" + - "5432" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - master-certs:/opt/conjur/etc/ssl/ + - ./system/backup:/opt/conjur/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs/master-5:/var/log/conjur:Z + - ./files:/conjur_files + + conjur-follower.mycompany.local: + image: haproxy:2.1-alpine + networks: + dap_net: + ipv4_address: 12.16.23.16 + ports: + - "80:80" + - "449:443" + - "7001:7000" + volumes: + - follower-certs:/etc/ssl/certs + - ./files/haproxy/follower:/usr/local/etc/haproxy + + conjur-follower-1.mycompany.local: + image: registry.tld/conjur-appliance:${VERSION} + networks: + dap_net: + ipv4_address: 12.16.23.17 + ports: + - "450:443" + expose: + - "443" + - "444" + security_opt: + - "seccomp:unconfined" + volumes: + - seeds:/opt/cyberark/dap/seeds + - follower-certs:/opt/conjur/etc/ssl/ + - ./system/backup:/opt/conjur/backup:Z + - ./system/configuration:/opt/cyberark/dap/configuration:Z + - ./system/logs/follower:/var/log/conjur:Z + - ./files:/conjur_files + + client: + image: cyberark/conjur-cli:5 + networks: + dap_net: + ipv4_address: 12.16.23.18 + working_dir: /src/cli + environment: + CONJUR_APPLIANCE_URL: https://conjur-master.mycompany.local + CONJUR_ACCOUNT: demo + CONJUR_AUTHN_LOGIN: admin + volumes: + - .:/src/cli + - ./cli_cache/master:/root + + follower-client: + image: cyberark/conjur-cli:5 + networks: + dap_net: + ipv4_address: 12.16.23.19 + working_dir: /src/cli + environment: + CONJUR_APPLIANCE_URL: https://conjur-follower.mycompany.local + CONJUR_ACCOUNT: demo + CONJUR_AUTHN_LOGIN: admin + volumes: + - .:/src/cli + - ./cli_cache/follower:/root + + api-client: + build: + context: ./artifacts/api-client + networks: + dap_net: + ipv4_address: 12.16.23.20 + working_dir: /src/ + volumes: + - ./artifacts/api-client/api-script:/src/bin/api + - ./policy:/src/policy + + certificate-generator: + build: + context: ./artifacts/certificate-generator + volumes: + - ./system/configuration/certificates:/src/certificates + +volumes: + seeds: + follower-certs: + master-certs: + +networks: + dap_net: + external: true diff --git a/docker_run.sh b/docker_run.sh index 754ea4f9..a34d3b1f 100644 --- a/docker_run.sh +++ b/docker_run.sh @@ -1,4 +1,4 @@ docker run -v /host/directory:/opt/conjur/backup --name conjur -d --restart=always \ - --security-opt seccomp:unconfined \ - -p "443:443" -p "636:636" -p "5432:5432" -p "5433:5433" \ + --security-opt seccomp:./seccomp.json \ + -p "443:443" -p "444:444" -p "636:636" -p "5432:5432" -p "5433:5433" \ registry.tld/conjur-appliance:4.9.18.0 diff --git a/features/cluster.feature b/features/cluster.feature new file mode 100644 index 00000000..08dca61a --- /dev/null +++ b/features/cluster.feature @@ -0,0 +1,40 @@ +Feature: A DAP cluster is deployed in a variety of configurations + +Scenario: I deploy a cluster for a non-production environments + Given I deploy a DAP master + And I deploy one follower + And I load a variable and value + When I request the variable value through the API + Then I get the variable value + And when I check the master audit log, I see the audit event + +Scenario: I deploy a cluster for a production environment + Given I deploy a DAP master with a load balancer + And I configure the master with custom certificates + And I deploy two standbys + And I configured the master and standby as an auto-failover cluster + And I deploy a follower with a load balancer + And I load a variable and value + When I request the variable value through the API + Then I get the variable value + And when I check the master audit log, I see the audit event + When I trigger a failover event + And I update the variable value + And I request the variable value through the API + Then I get the variable value + And when I check the master audit log, I see the audit event + +Scenario Outline: I can upgrade a cluster from one version to another + Given I deploy a DAP master with version + And I deploy one follower with version + And I load a variable and value + When I upgrade the master to the current version + And I upgrade the follower to the current version + And I request the variable value through the API + Then I get the variable value + And when I check the master audit log, I see the audit event + + Examples: DAP Releases + | release | + | 11.6.0 | + | 11.7.0 | diff --git a/features/step_definitions/dap_configuration.rb b/features/step_definitions/dap_configuration.rb new file mode 100644 index 00000000..3fa0c4ea --- /dev/null +++ b/features/step_definitions/dap_configuration.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + + +# Setup tasks +Given('I deploy a DAP master') do + @provider.provision_master(version: CURRENT_VERSION) +end + +Given('I deploy one follower') do + @provider.provision_follower(version: CURRENT_VERSION) +end + +Given('I deploy a DAP master with a load balancer') do + @provider.provision_master(version: CURRENT_VERSION, with_load_balancer: true) +end + +Given('I configure the master with custom certificates') do + @provider.import_custom_certificates +end + +Given('I deploy two standbys') do + @provider.provision_standbys(version: CURRENT_VERSION) +end + +Given('I configured the master and standby as an auto-failover cluster') do + @provider.enable_autofailover +end + +Given('I deploy a follower with a load balancer') do + @provider.provision_follower( + version: CURRENT_VERSION, + with_load_balancer: true + ) +end + +When('I trigger a failover event') do + @provider.trigger_auto_failover + @provider.wait_for_healthy_master +end + +Given('I deploy a DAP master with version {int}.{int}.{int}') do |int1, int2, int3| + @provider.provision_master(version: "#{int1}.#{int2}.#{int3}") +end + +Given('I deploy one follower with version {int}.{int}.{int}') do |int1, int2, int3| + @provider.provision_follower(version: "#{int1}.#{int2}.#{int3}") +end + +When('I upgrade the master to the current version') do + @provider.upgrade_master(version: CURRENT_VERSION) +end + +When('I upgrade the follower to the current version') do + @provider.provision_follower(version: CURRENT_VERSION) +end + +# Given('configured with {word} master key encryption') do |mke| +# pending # Write code here that turns the phrase above into concrete actions +# end diff --git a/features/step_definitions/dap_validation.rb b/features/step_definitions/dap_validation.rb new file mode 100644 index 00000000..98385e44 --- /dev/null +++ b/features/step_definitions/dap_validation.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# Validation tasks +Given('I load a variable and value') do + system('bin/api --load-policy-and-values') +end + +When('I request the variable value through the API') do + @variable_request = JSON.parse(`bin/api --fetch-secrets`) +end + +Then('I get the variable value') do + expect( + @variable_request['demo:variable:staging/my-app-1/postgres-database/password'] + ).to eq('secret-p@ssword-staging-my-app-1') +end + +Then('when I check the master audit log, I see the audit event') do + response = @provider.last_audit_event + expect(response['subject@43868']['resource']).to eq( + 'demo:variable:staging/my-app-1/postgres-database/port' + ) + expect(response['auth@43868']['user']).to eq('demo:user:admin') + expect(response['action@43868']['result']).to eq('success') +end + +When('I update the variable value') do + system('bin/api --set-secrets') +end diff --git a/features/step_definitions/world.rb b/features/step_definitions/world.rb new file mode 100644 index 00000000..d00722d4 --- /dev/null +++ b/features/step_definitions/world.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'logger' +require './ci/providers/docker_compose' + +CURRENT_VERSION = '12.0.0' + +def logger + @logger ||= begin + level = ENV['LOG_LEVEL'] || 'INFO' + log_level = Kernel.const_get("Logger::#{level.upcase}") + logger = Logger.new(STDOUT) + logger.level = log_level + logger + end +end + +def provider(type:) + @provider_cache ||= {} + @provider_cache[type] ||= begin + case type + when 'docker' + CI::Providers::DockerCompose.new(logger: logger) + else + raise "No Provider available for #{ENV['PROVIDER']}" + end + end +end + +Before do + @provider = provider(type: ENV['PROVIDER']) +end + +After do + @provider.reset_environment +end + +Given 'skip' do + skip_this_scenario +end diff --git a/features/support/env.rb b/features/support/env.rb new file mode 100644 index 00000000..410103ef --- /dev/null +++ b/features/support/env.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +at_exit do + provider(type: ENV['PROVIDER']).teardown +end diff --git a/files/cluster.conf b/files/cluster.conf new file mode 100644 index 00000000..a2cf128d --- /dev/null +++ b/files/cluster.conf @@ -0,0 +1,2 @@ +ETCD_PROXY_LOG_LEVEL=DEBUG +CONJUR_LOG_LEVEL=DEBUG diff --git a/files/dhparam.pem b/files/dhparam.pem new file mode 100644 index 00000000..8cf3970d --- /dev/null +++ b/files/dhparam.pem @@ -0,0 +1,14 @@ +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEA2TAv8VRdDnTTr4ft0z3LeLKvu7u6LrPl6zcGY3/fRH0MzhHEvYQz +sZ8Sn9JD/NaJdFCZqFHnqf009d9C53XSgkGcOTGpHlvKzga5VkhjjlsGjtwmdtKn +n1BqnvcY7jNd0nOlZyJuwCZ/+L8wAX+nuQN9eInWe+lOL3veAvhZCM4AnhI+VeFM +ARrcfUlGRa3sRQ+hBWMeAo9j/tsUbAbdb75KQZ1QcyTpI98l2fRKWaJWq+mtdmHo +lyqi5FqUBx+N65XqP4sbLcrCFo59iL59S3k+dDeHgivhfTUa1WEhKZ/Agisq803+ +WAPEOU4h5VY6EMhhtZl5lMW15//vz3oLGLWP0ZLn2u2zjUMZj2JFtuGvaXxK0BAp +70/949QRFb7SQ3OnlHby+t9jD1v/FeJE71rNVGvHCqvgJsdWxhEkddlqWGER4i+b +k7ME+8KP/3++TcK5/z8gLBnulXcqTTv4fSm46lP6DYLxhI9UhTfBEHmWpqhZug6h +qef+Lx4P7htGJjCYeW4+0ZwMkb89BUJi6SetvF8UlwGXLqjK2IxFc0JbbbONrR2l +uxYx5lNQyROcGIwivNDHXKV/t9JnN2QAK43NceXcUdVJAt8CWWT9tN0upVOTaziW +GtJk7LubrD87Dxev8cGsWjOJffpo6ZDGhLnu6qwSFYaFJJWFqrjdXusCAQI= +-----END DH PARAMETERS----- + diff --git a/files/etcd.conf b/files/etcd.conf new file mode 100644 index 00000000..d1d46aa3 --- /dev/null +++ b/files/etcd.conf @@ -0,0 +1,19 @@ +# Intentionally lowercase +http_proxy=http://localhost:2301 +no_proxy=${CLUSTER_MACHINE_NAME} + +ETCD_HEARTBEAT_INTERVAL=200 +ETCD_ELECTION_TIMEOUT=2000 + +ETCD_NAME=${CLUSTER_MACHINE_NAME} +ETCD_DATA_DIR=/var/lib/etcd + +ETCD_ADVERTISE_CLIENT_URLS=http://localhost:2379 +ETCD_LISTEN_CLIENT_URLS=http://localhost:2379 + +ETCD_INITIAL_ADVERTISE_PEER_URLS=http://${ETCD_NAME}:2380 +ETCD_LISTEN_PEER_URLS=http://localhost:2380 + +# Turning down the logging from these packages avoids blowing up the +# log when the network gets partitioned. +ETCD_LOG_PACKAGE_LEVELS=raft=DEBUG,rafthttp=DEBUG diff --git a/files/haproxy/follower/haproxy.cfg b/files/haproxy/follower/haproxy.cfg new file mode 100644 index 00000000..cfeb9581 --- /dev/null +++ b/files/haproxy/follower/haproxy.cfg @@ -0,0 +1,40 @@ +global + daemon + maxconn 256 + log-send-hostname + +defaults + mode http + option http-use-htx + option forwardfor + timeout connect 50000ms + timeout client 50000ms + timeout server 50000ms + +# +# Peform SSL Pass-Through to proxy HTTPS requests to DAP +# + +frontend www + bind *:80 + # bind *:443 ssl crt /etc/ssl/certs/conjur-follower.mycompany.local.pem + default_backend www-backend + +# +# Performs Layer 4 proxy +# Uses DAP's HTTP health endpoint to determine master +# + +backend www-backend + balance roundrobin + option httpchk GET /health + server conjur-follower-1 conjur-follower-1.mycompany.local:443 check port 443 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem ssl ca-file /etc/ssl/certs/ca.pem + +# +# Enables HAProxy's UI for debugging +# +listen stats + mode http + bind *:7000 + stats enable + stats uri / diff --git a/files/haproxy/master/multi-node/haproxy.cfg b/files/haproxy/master/multi-node/haproxy.cfg new file mode 100644 index 00000000..17080fc3 --- /dev/null +++ b/files/haproxy/master/multi-node/haproxy.cfg @@ -0,0 +1,90 @@ +global + daemon + maxconn 256 + log-send-hostname + +defaults + mode tcp + option http-use-htx + timeout connect 5000ms + timeout client 50000ms + timeout server 50000ms + +# +# Peform SSL Pass-Through to proxy HTTPS requests to DAP +# +frontend www + mode tcp + bind *:443 + option tcplog + default_backend www-backend + +# +# Peform SSL pass-through to proxy Postgres TCP requests from standbys/followers to DAP Master +# +frontend postgres + mode tcp + bind *:5432 + option tcplog + default_backend postgres-backend + +# +# Peform SSL pass-through to proxy Syslog TCP requests from followers to DAP Master +# +frontend syslog + mode tcp + bind *:1999 + option tcplog + default_backend syslog-backend + +# +# Performs Layer 4 proxy +# Uses DAP's HTTP health endpoint to determine master +# +backend www-backend + mode tcp + balance roundrobin + option httpchk GET /health + server conjur-master-1 conjur-master-1.mycompany.local:443 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-2 conjur-master-2.mycompany.local:443 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-3 conjur-master-3.mycompany.local:443 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-4 conjur-master-4.mycompany.local:443 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-5 conjur-master-5.mycompany.local:443 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + + +# +# Performs Layer 4 proxy +# Uses DAP's HTTP health endpoint to determine master +# +backend postgres-backend + mode tcp + balance roundrobin + option httpchk GET /health + server conjur-master-1 conjur-master-1.mycompany.local:5432 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-2 conjur-master-2.mycompany.local:5432 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-3 conjur-master-3.mycompany.local:5432 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-4 conjur-master-4.mycompany.local:5432 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-5 conjur-master-5.mycompany.local:5432 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + +# +# Performs Layer 4 proxy +# Uses DAP's HTTP health endpoint to determine master +# +backend syslog-backend + mode tcp + balance roundrobin + option httpchk GET /health + server conjur-master-1 conjur-master-1.mycompany.local:1999 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-2 conjur-master-2.mycompany.local:1999 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-3 conjur-master-3.mycompany.local:1999 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-4 conjur-master-4.mycompany.local:1999 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + server conjur-master-5 conjur-master-5.mycompany.local:1999 check port 443 check-ssl ca-file /etc/ssl/certs/ca.pem + +# +# Enables HAProxy's UI for debugging +# +listen stats + mode http + bind *:7000 + stats enable + stats uri / diff --git a/files/haproxy/master/single/haproxy.cfg b/files/haproxy/master/single/haproxy.cfg new file mode 100644 index 00000000..132862d5 --- /dev/null +++ b/files/haproxy/master/single/haproxy.cfg @@ -0,0 +1,38 @@ +global + daemon + maxconn 256 + log-send-hostname + +defaults + mode tcp + option http-use-htx + option tcplog + option httpchk GET /health + timeout connect 5000ms + timeout client 50000ms + timeout server 50000ms + +# +# Perform TCP Pass-Through to proxy HTTPS/TCP requests to DAP +# +frontend dap-frontend + # mode tcp + bind *:443 + bind *:1999 + bind *:5432 + bind *:5433 + + default_backend dap-backend + +backend dap-backend + balance roundrobin + server conjur-master-1 conjur-master-1.mycompany.local check port 444 + +# +# Enables HAProxy's UI for debugging +# +listen stats + mode http + bind *:7000 + stats enable + stats uri / diff --git a/load-modular b/load-modular new file mode 100755 index 00000000..cbf6eda3 --- /dev/null +++ b/load-modular @@ -0,0 +1,12 @@ +#!/bin/bash -ex + +./cli conjur policy load root policy/modular/root.yml +./cli conjur policy load --replace staging policy/modular/apps/applications.yml +./cli conjur policy load staging/my-app-1 policy/modular/apps/generic-application.yml +./cli conjur policy load staging/my-app-1 policy/modular/services/pg-database.yml + +./cli conjur variable values add staging/my-app-1/postgres-database/url https://foo-bar.mydatabase.com +./cli conjur variable values add staging/my-app-1/postgres-database/username my-app-user +./cli conjur variable values add staging/my-app-1/postgres-database/password super-secret-password +./cli conjur variable values add staging/my-app-1/postgres-database/port 5432 +./cli conjur policy load staging/my-app-1 policy/modular/entitlements/postgres-database.yml diff --git a/policy/application_grants.yml b/policy/application_grants.yml new file mode 100644 index 00000000..be297703 --- /dev/null +++ b/policy/application_grants.yml @@ -0,0 +1,4 @@ +# Grant the team_leads permission to read+write the "myapp" variables in production +- !grant + member: !group developers + role: !group staging/myapp/secrets-users diff --git a/policy/apps/myapp.yml b/policy/apps/myapp.yml new file mode 100644 index 00000000..3d6e6d2c --- /dev/null +++ b/policy/apps/myapp.yml @@ -0,0 +1,49 @@ +- !policy + id: myapp + body: + - &variables + - !variable + id: database/url + annotations: + description: Database URL + - !variable + id: database/port + annotations: + description: Database port + - !variable + id: database/username + annotations: + description: Application database username + - !variable + id: database/password + annotations: + description: Application database password + - !layer + + - !host-factory + layer: [ !layer ] + + - !group secrets-users + - !group secrets-managers + + # secrets-users can read and execute + - !permit + resource: *variables + privileges: [ read, execute ] + role: !group secrets-users + + # secrets-managers can update (and read and execute, via role grant) + - !permit + resource: *variables + privileges: [ update ] + role: !group secrets-managers + + # secrets-managers has role secrets-users + - !grant + member: !group secrets-managers + role: !group secrets-users + + # Application layer has the secrets-users role + - !grant + member: !layer + role: !group secrets-users diff --git a/policy/base.yml b/policy/base.yml new file mode 100644 index 00000000..9e9e275a --- /dev/null +++ b/policy/base.yml @@ -0,0 +1,4 @@ +- !policy + id: conjur + body: + - !policy cluster diff --git a/policy/cascading-delete-remove-namespace.yml b/policy/cascading-delete-remove-namespace.yml new file mode 100644 index 00000000..3d39ac28 --- /dev/null +++ b/policy/cascading-delete-remove-namespace.yml @@ -0,0 +1,2 @@ +- !delete + record: !policy myDemoApp diff --git a/policy/cascading-delete.yml b/policy/cascading-delete.yml new file mode 100644 index 00000000..138259bf --- /dev/null +++ b/policy/cascading-delete.yml @@ -0,0 +1,20 @@ +- !policy + id: myDemoApp + body: + - !user sasha + - !host app + - !variable secret + - !permit + roles: + - !user sasha + - !host app + privileges: [ read, execute ] + resources: !variable secret + +- !variable topSecret +- !permit + roles: + - !user sasha@myDemoApp + - !host myDemoApp/app + privileges: [ read, execute ] + resources: !variable topSecret diff --git a/policy/cluster.yml b/policy/cluster.yml new file mode 100644 index 00000000..40ebc4e0 --- /dev/null +++ b/policy/cluster.yml @@ -0,0 +1,16 @@ +- !policy + id: production + body: + - !layer + + # Host nodes to be enrolled in the `production` auto-failover cluster + - &hosts + - !host conjur-master-1.mycompany.local + - !host conjur-master-2.mycompany.local + - !host conjur-master-3.mycompany.local + - !host conjur-master-4.mycompany.local + - !host conjur-master-5.mycompany.local + + - !grant + role: !layer + member: *hosts diff --git a/policy/delete_policy/base.yml b/policy/delete_policy/base.yml new file mode 100644 index 00000000..5637f45c --- /dev/null +++ b/policy/delete_policy/base.yml @@ -0,0 +1 @@ +- !policy delete_branch diff --git a/policy/delete_policy/delete.yml b/policy/delete_policy/delete.yml new file mode 100644 index 00000000..18f50258 --- /dev/null +++ b/policy/delete_policy/delete.yml @@ -0,0 +1,2 @@ +- !delete + record: !policy second-level diff --git a/policy/delete_policy/first_level.yml b/policy/delete_policy/first_level.yml new file mode 100644 index 00000000..bf2ec1f8 --- /dev/null +++ b/policy/delete_policy/first_level.yml @@ -0,0 +1,3 @@ +- !policy + id: first-level + owner: !user /admin diff --git a/policy/delete_policy/second_level.yml b/policy/delete_policy/second_level.yml new file mode 100644 index 00000000..718c1ba5 --- /dev/null +++ b/policy/delete_policy/second_level.yml @@ -0,0 +1,8 @@ +- !policy + id: second-level + body: + - !host + id: third-level + annotations: + account: my-account + comment: A comment about this host diff --git a/policy/disappearing_host/10_add_host.yml b/policy/disappearing_host/10_add_host.yml new file mode 100644 index 00000000..e7a7c1e9 --- /dev/null +++ b/policy/disappearing_host/10_add_host.yml @@ -0,0 +1,2 @@ +- !host + id: testhost1 diff --git a/policy/disappearing_host/11_remove_host.yml b/policy/disappearing_host/11_remove_host.yml new file mode 100644 index 00000000..2801efda --- /dev/null +++ b/policy/disappearing_host/11_remove_host.yml @@ -0,0 +1,2 @@ +- !delete + record: !host testhost1 diff --git a/policy/duplicate-webservices.yml b/policy/duplicate-webservices.yml new file mode 100644 index 00000000..2a8f8da6 --- /dev/null +++ b/policy/duplicate-webservices.yml @@ -0,0 +1,2 @@ +- !webservice test-webservice-1 +- !webservice test-webservice-2 diff --git a/policy/hosts.yml b/policy/hosts.yml new file mode 100644 index 00000000..4496efc9 --- /dev/null +++ b/policy/hosts.yml @@ -0,0 +1 @@ +- !host test-host-1 diff --git a/policy/logs_policy/conjur_policy_v5.yml b/policy/logs_policy/conjur_policy_v5.yml new file mode 100755 index 00000000..4adff856 --- /dev/null +++ b/policy/logs_policy/conjur_policy_v5.yml @@ -0,0 +1,102 @@ +# conjur_policy.yml +--- + +- !host conjurhost + +- !layer conjurlayer + +- !grant + role: !host conjurhost + member: !layer conjurlayer + +- &mongo-variables + - !variable mongo/host + - !variable mongo/port + - !variable mongo/username + - !variable mongo/password + +- !permit + resource: *mongo-variables + privileges: [ read, execute ] + roles: !layer conjurlayer + +- &rabbitmq-variables + - !variable rabbitmq/host + - !variable rabbitmq/port + - !variable rabbitmq/user + - !variable rabbitmq/password + +- !permit + resource: *rabbitmq-variables + privileges: [ read, execute ] + roles: !layer conjurlayer + +- !variable redis/host + +- !permit + resource: !variable redis/host + privileges: [ read, execute ] + roles: !layer conjurlayer + +- !variable aws/masterkeyid + +- !permit + resource: !variable aws/masterkeyid + privileges: [ read, execute ] + roles: !layer conjurlayer + +- &jwt-variables + - !variable jwt/remoteurl + - !variable jwt/password + +- !permit + resource: *jwt-variables + privileges: [ read, execute ] + roles: !layer conjurlayer + +- ¬ification-variables + - !variable notification/invitecodebaseurl + - !variable notification/invitesendpoint/url + - !variable notification/awssns/accesskey + - !variable notification/awssns/secretkey + - !variable notification/awssns/platform + - !variable notification/awssns/com.insulet.dash.display + - !variable notification/awssns/com.insulet.dash.view + - !variable notification/snaplogic/url + - !variable notification/snaplogic/authorizationtoken + - !variable notification/notificationservicebaseurl + +- !permit + resource: *notification-variables + privileges: [ read, execute ] + roles: !layer conjurlayer + +- &display-variables + - !variable display/dataservicebaseurl + - !variable display/authenticationserviceapikey + - !variable display/authenticationservicebaseurl + +- !permit + resource: *display-variables + privileges: [ read, execute ] + roles: !layer conjurlayer + +- &view-variables + - !variable view/authenticationserviceapikey + - !variable view/dataservicebaseurl + - !variable view/mfgservicebaseurl + - !variable view/authenticationservicebaseurl + +- !permit + resource: *view-variables + privileges: [ read, execute ] + roles: !layer conjurlayer + +- &support-variables + - !variable support/mfgserviceurl + - !variable support/dataserviceurl + +- !permit + resource: *support-variables + privileges: [ read, execute ] + roles: !layer conjurlayer \ No newline at end of file diff --git a/policy/logs_policy/logs.txt b/policy/logs_policy/logs.txt new file mode 100755 index 00000000..1097c4cd --- /dev/null +++ b/policy/logs_policy/logs.txt @@ -0,0 +1,15 @@ +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: I, [2019-03-08T20:18:49.728719 #5562] INFO -- : Started GET "/authn/Insulet/login" for 127.0.0.1 at 2019-03-08 20:18:49 +0000 +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: I, [2019-03-08T20:18:49.729531 #5562] INFO -- : Processing by AuthenticateController#login as */* +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: I, [2019-03-08T20:18:49.729578 #5562] INFO -- : Parameters: {"authenticator"=>"authn", "account"=>"Insulet"} +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: I, [2019-03-08T20:18:49.733456 #5562] INFO -- : Completed 500 Internal Server Error in 4ms +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: F, [2019-03-08T20:18:49.737204 #5562] FATAL -- : +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: NoMethodError (undefined method `id' for nil:NilClass): +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: app/domain/authentication/strategy.rb:235:in `new_login' +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: app/domain/authentication/strategy.rb:84:in `login' +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: app/controllers/concerns/basic_authenticator.rb:30:in `authenticator_login' +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: app/controllers/concerns/basic_authenticator.rb:14:in `block in perform_basic_authn' +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: app/controllers/concerns/basic_authenticator.rb:13:in `perform_basic_authn' +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: app/controllers/authenticate_controller.rb:22:in `login' +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: app/controllers/application_controller.rb:42:in `block in run_with_transaction' +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: app/controllers/application_controller.rb:41:in `run_with_transaction' +2019-03-08T20:18:50.327+00:00 17a899849b53 conjur-possum: lib/rack/remember_uuid.rb:12:in `call' \ No newline at end of file diff --git a/policy/logs_policy/rootpolicy.yml b/policy/logs_policy/rootpolicy.yml new file mode 100755 index 00000000..712dd106 --- /dev/null +++ b/policy/logs_policy/rootpolicy.yml @@ -0,0 +1,19 @@ +--- +- !policy conjur/cluster + +- !group conjur-root-admins + +- !permit + role: !group conjur-root-admins + privileges: [ create, update, read ] + resources: + - !policy root + +- !policy + id: awskeys + owner: !group conjur-root-admins + +- !policy + id: dashdev + owner: !group conjur-root-admins + diff --git a/policy/modular/README.md b/policy/modular/README.md new file mode 100644 index 00000000..43d4ddf6 --- /dev/null +++ b/policy/modular/README.md @@ -0,0 +1,39 @@ +# Modular Policy Example + +This folder includes an example of how to build a modular, template-based set of policies. Modular +templates means we only need to manage a unique set applications. The rest of the relationships can be +loaded using the namespaces generated by this original set of policies. + +## Installation + +1. Create a `staging` and `production` namespace: + ```sh + $ ./cli conjur policy load root policy/modular/root.yml + ``` +2. Create namespaces for each of our applications (`my-app-1..my-app-6`) in the staging namespace: + ```sh + $ ./cli conjur policy load staging policy/modular/apps/applications.yml + ``` +3. Create our first application `my-app-1`, in the staging environment: + ```sh + $ ./cli conjur policy load staging/my-app-1 policy/modular/apps/generic-application.yml + ``` + +4. Create our a database connection for our application `my-app-1`, in the staging environment: + ```sh + $ ./cli conjur policy load staging/my-app-1 policy/modular/services/pg-database.yml + ``` + +5. Grant our layer permission to retrieve database connection information: + ```sh + $ ./cli conjur policy load staging/my-app-1 policy/modular/pg-entitlement.yml + ``` + +6. Now we can set the database connection information: + ```sh + $ ./cli conjur variable values add staging/my-app-1/postgres-database/password super-secret + ... + ``` + +With the above, we've created an application (`staging/my-app-1`), created a database (`staging/my-app-1/postgres-database`), +and granted the application read access to the application layer. diff --git a/policy/modular/apps/applications.yml b/policy/modular/apps/applications.yml new file mode 100644 index 00000000..80afce52 --- /dev/null +++ b/policy/modular/apps/applications.yml @@ -0,0 +1,6 @@ +- !policy my-app-1 +- !policy my-app-2 +- !policy my-app-3 +- !policy my-app-4 +- !policy my-app-5 +- !policy my-app-6 diff --git a/policy/modular/apps/generic-application.yml b/policy/modular/apps/generic-application.yml new file mode 100644 index 00000000..a5016286 --- /dev/null +++ b/policy/modular/apps/generic-application.yml @@ -0,0 +1,7 @@ +- !policy + id: application + body: + - !layer + + # - !host-factory + # layer: [ !layer ] diff --git a/policy/modular/pg-entitlement.yml b/policy/modular/pg-entitlement.yml new file mode 100644 index 00000000..6b4f2ebd --- /dev/null +++ b/policy/modular/pg-entitlement.yml @@ -0,0 +1,3 @@ +- !grant + member: !layer application + role: !group postgres-database/secrets-users diff --git a/policy/modular/root.yml b/policy/modular/root.yml new file mode 100644 index 00000000..e81c9a1b --- /dev/null +++ b/policy/modular/root.yml @@ -0,0 +1,12 @@ +- !group team_leads +- !group security_ops + +# Define "staging" namespace, owned by the "team_leads" +- !policy + id: staging + owner: !group team_leads + +# Define "production" namespace, owned by the "security_ops" team +- !policy + id: production + owner: !group security_ops diff --git a/policy/modular/services/pg-database.yml b/policy/modular/services/pg-database.yml new file mode 100644 index 00000000..bbcb3dc5 --- /dev/null +++ b/policy/modular/services/pg-database.yml @@ -0,0 +1,40 @@ +- !policy + id: postgres-database + body: + - &variables + - !variable + id: username + annotations: + description: Database username + - !variable + id: password + annotations: + description: Database password + - !variable + id: url + annotations: + description: Database URL + - !variable + id: port + annotations: + description: Database port + + - !group secrets-users + - !group secrets-managers + + # secrets-users can read and execute + - !permit + resource: *variables + privileges: [ read, execute ] + role: !group secrets-users + + # secrets-managers can update (and read and execute, via role grant) + - !permit + resource: *variables + privileges: [ update ] + role: !group secrets-managers + + # secrets-managers has role secrets-users + - !grant + member: !group secrets-managers + role: !group secrets-users diff --git a/policy/policy.yml b/policy/policy.yml new file mode 100644 index 00000000..d21fb22b --- /dev/null +++ b/policy/policy.yml @@ -0,0 +1,13 @@ +# Top-level policy file +- !group team_leads +- !group security_ops + +# Define "staging" namespace, owned by the "team_leads" +- !policy + id: staging + owner: !group team_leads + +# Define "production" namespace, owned by the "security_ops" team +- !policy + id: production + owner: !group security_ops diff --git a/policy/seed-service/default.yml b/policy/seed-service/default.yml new file mode 100644 index 00000000..767ddf23 --- /dev/null +++ b/policy/seed-service/default.yml @@ -0,0 +1 @@ +- !policy conjur diff --git a/policy/seed-service/seed.yml b/policy/seed-service/seed.yml new file mode 100644 index 00000000..e8902780 --- /dev/null +++ b/policy/seed-service/seed.yml @@ -0,0 +1,25 @@ +- !webservice seed-generation +- !layer masters +- !layer followers + +- !group seed-service + +- !permit + role: !group seed-service + resource: !webservice seed-generation + privileges: [ "execute" ] + +- !grant + members: + - !layer masters + - !layer followers + role: !group seed-service + +- !host master-2 +- !host master-3 + +- !grant + members: + - !host master-2 + - !host master-3 + role: !layer masters diff --git a/policy/test-host-user.yml b/policy/test-host-user.yml new file mode 100644 index 00000000..78f48d03 --- /dev/null +++ b/policy/test-host-user.yml @@ -0,0 +1,9 @@ +- !host my-host +- !group my-group +- !user fred + +- !grant + members: + - !host my-host + - !user fred + role: !group my-group diff --git a/policy/users.yml b/policy/users.yml new file mode 100644 index 00000000..ddf4b093 --- /dev/null +++ b/policy/users.yml @@ -0,0 +1,72 @@ +- !group security_ops +- !group team_leads +- !group developers + +- !user + id: jason.vanderhoof + annotations: + first_name: Jason + last_name: Vanderhoof + email: jason.vanderhoof@cyberark.com + +- !user + id: marcel.calisto + annotations: + first_name: Marcel + last_name: Calisto + email: marcel.calisto@cyberark.com + +- !user + id: ernest.alvin + annotations: + first_name: Ernest + last_name: Alvin + email: ernest.alvin@cyberark.com + +- !user + id: victoria.nandita + annotations: + first_name: Victoria + last_name: Nandita + email: victoria.nandita@cyberark.com + +- !user + id: sophie.madelon + annotations: + first_name: Sophie + last_name: Madelon + email: sophie.madelon@cyberark.com + +- !user + id: terrance.blake + annotations: + first_name: Terrance + last_name: Blake + email: terrance.blake@cyberark.com + +- !grant + role: !group developers + members: + - !user marcel.calisto + - !user ernest.alvin + - !user sophie.madelon + +- !grant + role: !group team_leads + members: + - !user jason.vanderhoof + - !user victoria.nandita + +- !grant + role: !group security_ops + members: + - !user terrance.blake + +# Grant the less-powerful groups to the more-powerful groups +- !grant + member: !group team_leads + role: !group developers + +- !grant + member: !group security_ops + role: !group team_leads diff --git a/policy/vault-synchronizer-viewer-role/main.yml b/policy/vault-synchronizer-viewer-role/main.yml new file mode 100644 index 00000000..b973f122 --- /dev/null +++ b/policy/vault-synchronizer-viewer-role/main.yml @@ -0,0 +1,69 @@ +- !group synchronizer-admin + +# -- Start New -- +- !group synchronizer-auditor +# -- End New -- + +- !policy + id: enterpise-password-vault + owner: !group synchronizer-admin + body: + - !group lob-1-viewer + + - !group lob-1-admin + - !policy + id: lob-1 + owner: !group lob-1-admin + body: + - !group safe-1-admin + - !policy + id: safe-1 + owner: !group safe-1-admin + body: + - &variables + - !variable database-1-url + - !variable database-1-username + - !variable database-1-password + - !variable database-1-port + - !variable database-1-ca + - !variable database-1-certifiate + + - !group consumers + - !permit + resource: *variables + # privileges: [ read, execute ] + privileges: [ execute ] + role: !group consumers + + # -- Start New -- + - !group viewers + - !permit + resource: *variables + privileges: [ read ] + role: !group viewers + + - !grant + role: !group viewers + members: + - !group consumers + - !group lob-1-viewer + + - !grant + member: !group /synchronizer-auditor + role: !group viewers + # -- End New -- + + - !policy safe-2 + - !policy safe-3 + - !policy safe-4 + + # - !grant + # role: !group lob-1-admin + # member: !group /synchronizer-admin + + +# Create an audit user to verify via UI +- !user jason +- !grant + member: !user jason + role: !group synchronizer-auditor diff --git a/seccomp.json b/seccomp.json new file mode 100644 index 00000000..874ed1ae --- /dev/null +++ b/seccomp.json @@ -0,0 +1,792 @@ +{ + "description": "Default Docker seccomp profile, plus keyctl, add_key, request_key calls (required by Dynamic Access Provider)", + "comment": "Run with `docker run --security seccomp:path/to/seccomp.json` to use it.", + "defaultAction": "SCMP_ACT_ERRNO", + "architectures": [ + "SCMP_ARCH_X86_64", + "SCMP_ARCH_X86", + "SCMP_ARCH_X32" + ], + "syscalls": [ + { + "names": [ + "accept", + "accept4", + "access", + "adjtimex", + "alarm", + "bind", + "brk", + "capget", + "capset", + "chdir", + "chmod", + "chown", + "chown32", + "clock_getres", + "clock_getres_time64", + "clock_gettime", + "clock_gettime64", + "clock_nanosleep", + "clock_nanosleep_time64", + "close", + "connect", + "copy_file_range", + "creat", + "dup", + "dup2", + "dup3", + "epoll_create", + "epoll_create1", + "epoll_ctl", + "epoll_ctl_old", + "epoll_pwait", + "epoll_wait", + "epoll_wait_old", + "eventfd", + "eventfd2", + "execve", + "execveat", + "exit", + "exit_group", + "faccessat", + "fadvise64", + "fadvise64_64", + "fallocate", + "fanotify_mark", + "fchdir", + "fchmod", + "fchmodat", + "fchown", + "fchown32", + "fchownat", + "fcntl", + "fcntl64", + "fdatasync", + "fgetxattr", + "flistxattr", + "flock", + "fork", + "fremovexattr", + "fsetxattr", + "fstat", + "fstat64", + "fstatat64", + "fstatfs", + "fstatfs64", + "fsync", + "ftruncate", + "ftruncate64", + "futex", + "futex_time64", + "futimesat", + "getcpu", + "getcwd", + "getdents", + "getdents64", + "getegid", + "getegid32", + "geteuid", + "geteuid32", + "getgid", + "getgid32", + "getgroups", + "getgroups32", + "getitimer", + "getpeername", + "getpgid", + "getpgrp", + "getpid", + "getppid", + "getpriority", + "getrandom", + "getresgid", + "getresgid32", + "getresuid", + "getresuid32", + "getrlimit", + "get_robust_list", + "getrusage", + "getsid", + "getsockname", + "getsockopt", + "get_thread_area", + "gettid", + "gettimeofday", + "getuid", + "getuid32", + "getxattr", + "inotify_add_watch", + "inotify_init", + "inotify_init1", + "inotify_rm_watch", + "io_cancel", + "ioctl", + "io_destroy", + "io_getevents", + "io_pgetevents", + "io_pgetevents_time64", + "ioprio_get", + "ioprio_set", + "io_setup", + "io_submit", + "io_uring_enter", + "io_uring_register", + "io_uring_setup", + "ipc", + "kill", + "lchown", + "lchown32", + "lgetxattr", + "link", + "linkat", + "listen", + "listxattr", + "llistxattr", + "_llseek", + "lremovexattr", + "lseek", + "lsetxattr", + "lstat", + "lstat64", + "madvise", + "memfd_create", + "mincore", + "mkdir", + "mkdirat", + "mknod", + "mknodat", + "mlock", + "mlock2", + "mlockall", + "mmap", + "mmap2", + "mprotect", + "mq_getsetattr", + "mq_notify", + "mq_open", + "mq_timedreceive", + "mq_timedreceive_time64", + "mq_timedsend", + "mq_timedsend_time64", + "mq_unlink", + "mremap", + "msgctl", + "msgget", + "msgrcv", + "msgsnd", + "msync", + "munlock", + "munlockall", + "munmap", + "nanosleep", + "newfstatat", + "_newselect", + "open", + "openat", + "pause", + "pipe", + "pipe2", + "poll", + "ppoll", + "ppoll_time64", + "prctl", + "pread64", + "preadv", + "preadv2", + "prlimit64", + "pselect6", + "pselect6_time64", + "pwrite64", + "pwritev", + "pwritev2", + "read", + "readahead", + "readlink", + "readlinkat", + "readv", + "recv", + "recvfrom", + "recvmmsg", + "recvmmsg_time64", + "recvmsg", + "remap_file_pages", + "removexattr", + "rename", + "renameat", + "renameat2", + "restart_syscall", + "rmdir", + "rt_sigaction", + "rt_sigpending", + "rt_sigprocmask", + "rt_sigqueueinfo", + "rt_sigreturn", + "rt_sigsuspend", + "rt_sigtimedwait", + "rt_sigtimedwait_time64", + "rt_tgsigqueueinfo", + "sched_getaffinity", + "sched_getattr", + "sched_getparam", + "sched_get_priority_max", + "sched_get_priority_min", + "sched_getscheduler", + "sched_rr_get_interval", + "sched_rr_get_interval_time64", + "sched_setaffinity", + "sched_setattr", + "sched_setparam", + "sched_setscheduler", + "sched_yield", + "seccomp", + "select", + "semctl", + "semget", + "semop", + "semtimedop", + "semtimedop_time64", + "send", + "sendfile", + "sendfile64", + "sendmmsg", + "sendmsg", + "sendto", + "setfsgid", + "setfsgid32", + "setfsuid", + "setfsuid32", + "setgid", + "setgid32", + "setgroups", + "setgroups32", + "setitimer", + "setpgid", + "setpriority", + "setregid", + "setregid32", + "setresgid", + "setresgid32", + "setresuid", + "setresuid32", + "setreuid", + "setreuid32", + "setrlimit", + "set_robust_list", + "setsid", + "setsockopt", + "set_thread_area", + "set_tid_address", + "setuid", + "setuid32", + "setxattr", + "shmat", + "shmctl", + "shmdt", + "shmget", + "shutdown", + "sigaltstack", + "signalfd", + "signalfd4", + "sigprocmask", + "sigreturn", + "socket", + "socketcall", + "socketpair", + "splice", + "stat", + "stat64", + "statfs", + "statfs64", + "statx", + "symlink", + "symlinkat", + "sync", + "sync_file_range", + "syncfs", + "sysinfo", + "tee", + "tgkill", + "time", + "timer_create", + "timer_delete", + "timer_getoverrun", + "timer_gettime", + "timer_gettime64", + "timer_settime", + "timer_settime64", + "timerfd_create", + "timerfd_gettime", + "timerfd_gettime64", + "timerfd_settime", + "timerfd_settime64", + "times", + "tkill", + "truncate", + "truncate64", + "ugetrlimit", + "umask", + "uname", + "unlink", + "unlinkat", + "utime", + "utimensat", + "utimensat_time64", + "utimes", + "vfork", + "vmsplice", + "wait4", + "waitid", + "waitpid", + "write", + "writev" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": {}, + "excludes": {} + }, + { + "names": [ + "ptrace" + ], + "action": "SCMP_ACT_ALLOW", + "args": null, + "comment": "", + "includes": { + "minKernel": "4.8" + }, + "excludes": {} + }, + { + "names": [ + "personality" + ], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 0, + "valueTwo": 0, + "op": "SCMP_CMP_EQ" + } + ], + "comment": "", + "includes": {}, + "excludes": {} + }, + { + "names": [ + "personality" + ], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 8, + "valueTwo": 0, + "op": "SCMP_CMP_EQ" + } + ], + "comment": "", + "includes": {}, + "excludes": {} + }, + { + "names": [ + "personality" + ], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 131072, + "valueTwo": 0, + "op": "SCMP_CMP_EQ" + } + ], + "comment": "", + "includes": {}, + "excludes": {} + }, + { + "names": [ + "personality" + ], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 131080, + "valueTwo": 0, + "op": "SCMP_CMP_EQ" + } + ], + "comment": "", + "includes": {}, + "excludes": {} + }, + { + "names": [ + "personality" + ], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 4294967295, + "valueTwo": 0, + "op": "SCMP_CMP_EQ" + } + ], + "comment": "", + "includes": {}, + "excludes": {} + }, + { + "names": [ + "sync_file_range2" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "arches": [ + "ppc64le" + ] + }, + "excludes": {} + }, + { + "names": [ + "arm_fadvise64_64", + "arm_sync_file_range", + "sync_file_range2", + "breakpoint", + "cacheflush", + "set_tls" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "arches": [ + "arm", + "arm64" + ] + }, + "excludes": {} + }, + { + "names": [ + "arch_prctl" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "arches": [ + "amd64", + "x32" + ] + }, + "excludes": {} + }, + { + "names": [ + "modify_ldt" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "arches": [ + "amd64", + "x32", + "x86" + ] + }, + "excludes": {} + }, + { + "names": [ + "s390_pci_mmio_read", + "s390_pci_mmio_write", + "s390_runtime_instr" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "arches": [ + "s390", + "s390x" + ] + }, + "excludes": {} + }, + { + "names": [ + "open_by_handle_at" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_DAC_READ_SEARCH" + ] + }, + "excludes": {} + }, + { + "names": [ + "bpf", + "clone", + "fanotify_init", + "lookup_dcookie", + "mount", + "name_to_handle_at", + "perf_event_open", + "quotactl", + "setdomainname", + "sethostname", + "setns", + "syslog", + "umount", + "umount2", + "unshare" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_ADMIN" + ] + }, + "excludes": {} + }, + { + "names": [ + "clone" + ], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 2114060288, + "valueTwo": 0, + "op": "SCMP_CMP_MASKED_EQ" + } + ], + "comment": "", + "includes": {}, + "excludes": { + "caps": [ + "CAP_SYS_ADMIN" + ], + "arches": [ + "s390", + "s390x" + ] + } + }, + { + "names": [ + "clone" + ], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 1, + "value": 2114060288, + "valueTwo": 0, + "op": "SCMP_CMP_MASKED_EQ" + } + ], + "comment": "s390 parameter ordering for clone is different", + "includes": { + "arches": [ + "s390", + "s390x" + ] + }, + "excludes": { + "caps": [ + "CAP_SYS_ADMIN" + ] + } + }, + { + "names": [ + "reboot" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_BOOT" + ] + }, + "excludes": {} + }, + { + "names": [ + "chroot" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_CHROOT" + ] + }, + "excludes": {} + }, + { + "names": [ + "delete_module", + "init_module", + "finit_module", + "query_module" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_MODULE" + ] + }, + "excludes": {} + }, + { + "names": [ + "acct" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_PACCT" + ] + }, + "excludes": {} + }, + { + "names": [ + "kcmp", + "process_vm_readv", + "process_vm_writev", + "ptrace" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_PTRACE" + ] + }, + "excludes": {} + }, + { + "names": [ + "iopl", + "ioperm" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_RAWIO" + ] + }, + "excludes": {} + }, + { + "names": [ + "settimeofday", + "stime", + "clock_settime" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_TIME" + ] + }, + "excludes": {} + }, + { + "names": [ + "vhangup" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_TTY_CONFIG" + ] + }, + "excludes": {} + }, + { + "names": [ + "get_mempolicy", + "mbind", + "set_mempolicy" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYS_NICE" + ] + }, + "excludes": {} + }, + { + "names": [ + "syslog" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "", + "includes": { + "caps": [ + "CAP_SYSLOG" + ] + }, + "excludes": {} + }, + { + "name": "add_key", + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "required by Dynamic Access Provider (DAP)" + }, + { + "name": "keyctl", + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "required by Dynamic Access Provider (DAP)" + }, + { + "name": "request_key", + "action": "SCMP_ACT_ALLOW", + "args": [], + "comment": "required by Dynamic Access Provider (DAP)" + } + ] +} diff --git a/system/configuration/dap.json b/system/configuration/dap.json new file mode 100644 index 00000000..e69de29b diff --git a/system/security/seccomp.json b/system/security/seccomp.json new file mode 100644 index 00000000..e69de29b diff --git a/tools/performance-tests/Dockerfile b/tools/performance-tests/Dockerfile new file mode 100644 index 00000000..3a290d43 --- /dev/null +++ b/tools/performance-tests/Dockerfile @@ -0,0 +1,36 @@ +# inspired by https://hub.docker.com/r/justb4/jmeter +FROM alpine:3.10 + +MAINTAINER Just van den Broecke + +ENV JMETER_VERSION="5.2.1" +ENV JMETER_HOME /opt/apache-jmeter-${JMETER_VERSION} +ENV JMETER_BIN ${JMETER_HOME}/bin +ENV JMETER_DOWNLOAD_URL https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.tgz + +# Install extra packages +# See https://github.com/gliderlabs/docker-alpine/issues/136#issuecomment-272703023 +# Change TimeZone TODO: TZ still is not set! +ARG TZ="Europe/Amsterdam" +RUN apk update \ + && apk upgrade \ + && apk add ca-certificates \ + && update-ca-certificates \ + && apk add --update openjdk11-jre tzdata curl unzip bash \ + && apk add --no-cache nss \ + && rm -rf /var/cache/apk/* \ + && mkdir -p /tmp/dependencies \ + && curl -L --silent ${JMETER_DOWNLOAD_URL} > /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz \ + && mkdir -p /opt \ + && tar -xzf /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz -C /opt \ + && rm -rf /tmp/dependencies + +# TODO: plugins (later) +# && unzip -oq "/tmp/dependencies/JMeterPlugins-*.zip" -d $JMETER_HOME + +# Set global PATH such that "jmeter" command is found +ENV PATH $PATH:$JMETER_BIN + +WORKDIR ${JMETER_HOME} + +RUN mkdir /opt/jmeter_data diff --git a/tools/performance-tests/README.md b/tools/performance-tests/README.md new file mode 100644 index 00000000..ccbc9f09 --- /dev/null +++ b/tools/performance-tests/README.md @@ -0,0 +1,69 @@ +# Jmeter Performance Test + +## How to run +- To run the performance test on the latest DAP version: + + ```sh + $ bin/run + ``` + +- To run the performance test against a particular DAP release: + + ```sh + $ bin/run --tag 11.3 + ``` + +- To view all possible commands: + + ```sh + $ bin/run --help + ``` + +The script will: +1. Start and configure a DAP master. +1. Using JMeter, run the performance test specified in `jmeter/DAP_Performance_Test.jmx`. +1. Upon test completion, shut down all containers and open the results in a browser. + +The script will exit upon completion of the JMeter tests, outputting the results in the `jmeter/jmeter_reports` folder + + +## Results +After run a test, the test results are available in `jmeter/jmeter_reports/`. The folder will include two files that may be of use: +1. `index.html` contains a nice page with aggregrate reports +2. `DAP_Performance_Results.csv` is a more in depth report, containing information regarding each individual jmeter request. + +## Current Test +1. Authenticate as the admin user +2. Load the following policies (from conjurdemos/dap-intro): + - policy/users.yml (into the root namespace, using [replace](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Developer/Conjur_API_Replace_Policy.htm?tocpath=Developer%7CREST%C2%A0APIs%7C_____9)) + - policy/policy.yml (into the root namespace using [append](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Developer/Conjur_API_Append_Policy.htm?tocpath=Developer%7CREST%C2%A0APIs%7C_____10)) + - policy/apps/myapp.yml (into the staging namespace using [append](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Developer/Conjur_API_Append_Policy.htm?tocpath=Developer%7CREST%C2%A0APIs%7C_____10)) + - policy/apps/myapp.yml (into the production namespace using [append](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Developer/Conjur_API_Append_Policy.htm?tocpath=Developer%7CREST%C2%A0APIs%7C_____10)) + - policy/application_grants.yml (into the root namespace using [append](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Developer/Conjur_API_Append_Policy.htm?tocpath=Developer%7CREST%C2%A0APIs%7C_____10)) + - policy/hosts.yml (into the root namespace using [append](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Developer/Conjur_API_Append_Policy.htm?tocpath=Developer%7CREST%C2%A0APIs%7C_____10)) + - Record the test-host-1 API key for future use + +3. Set the following variables with random strings: + - production/myapp/database/username + - production/myapp/database/password + - production/myapp/database/url + - production/myapp/database/port + +4. Load Test: + - Authenticate using the test-host-1 API key and retrieve a token + - Retrieve the production/myapp/database credentials using batch retrieval + + +## Contributing +Install JMeter on OSX: +1. Install JMeter using Brew: + ```sh + $ brew install jmeter + ``` +2. Open the file using the JMeter: + ```sh + $ jmeter -t DAP_Performance_Test.jmx + ``` + +Optionally, you install JMeter manually: +Download [Jmeter](http://jmeter.apache.org/download_jmeter.cgi) and edit the `.jmx` file diff --git a/tools/performance-tests/bin/run b/tools/performance-tests/bin/run new file mode 100755 index 00000000..8daeda2c --- /dev/null +++ b/tools/performance-tests/bin/run @@ -0,0 +1,84 @@ +#!/bin/bash -ex + +function finish { + docker-compose down -v +} + +function configure_dap_instance { + local config + config="$1" + + docker-compose up -d --no-deps dap + docker-compose exec dap bash -c " + evoke configure master $config -h conjur-master.local -p MySecretP@ss1 --accept-eula demo + " +} + +function print_help() { + cat << EOF +NAME + Starts and configures a Conjur Appliance. Once Conjur is configured, the + appliance logs are streamed. + + +SYNOPSIS + start [global options] + +GLOBAL OPTIONS + -h, --help - Show this message + + --skip-pull - Does not pull a fresh Conjur master before starting + + -t, --tag - Runs load test against the specified DAP Appliance tag + + --with-config - Configures the Appliance using the `config/conjur.json` file + +EOF +exit +} + +function cleanup { + local folder + folder="$1" + rm -rf jmeter/jmeter_reports/$folder/* +} + +function run_jmeter_test { + docker-compose up --no-deps jmeter +} + +function open_results_in_browser { + local version + version="$1" + open jmeter/jmeter_reports/$version/index.html +} + +function main { + cleanup + configure_dap_instance $CONFIG + run_jmeter_test $DAP_TAG + open_results_in_browser $DAP_TAG +} + +PULL_ARGS="--pull" +DAP_TAG="5.0-stable" +CONFIG="" +while true ; do + case "$1" in + --skip-pull ) PULL_ARGS="" ; shift ;; + -h | --help ) print_help ; shift ;; + -t | --tag ) shift ; DAP_TAG="$1" ; shift ;; + --with-config ) CONFIG="-j /opt/config/conjur.json" ; shift ;; + * ) if [ -z "$1" ]; then break; else echo "$1 is not a valid option"; exit 1; fi;; + esac +done + +trap finish EXIT + +export DAP_VERSION=$DAP_TAG + +if [ "$PULL_ARGS" == "--pull" ]; then + docker pull registry.tld/conjur-appliance:$DAP_VERSION +fi + +main diff --git a/tools/performance-tests/docker-compose.yml b/tools/performance-tests/docker-compose.yml new file mode 100644 index 00000000..ecf9aed8 --- /dev/null +++ b/tools/performance-tests/docker-compose.yml @@ -0,0 +1,20 @@ +version: "3" +services: + dap: + image: registry.tld/conjur-appliance:${DAP_VERSION} + ports: + - "443:443" + security_opt: + - "seccomp:../../seccomp.json" + volumes: + - ../config:/opt/config:Z + - ../logs:/var/log/conjur:z + + jmeter: + build: + context: . + volumes: + - ./jmeter:/opt/jmeter_data + command: jmeter -Jkey=null -n -t /opt/jmeter_data/DAP_Performance_Test.jmx -l /opt/jmeter_data/jmeter_reports/${DAP_VERSION}/DAP_Performance_Results.csv -e -o /opt/jmeter_data/jmeter_reports/${DAP_VERSION} + depends_on: + - dap diff --git a/tools/performance-tests/jmeter/DAP_Performance_Test.jmx b/tools/performance-tests/jmeter/DAP_Performance_Test.jmx new file mode 100644 index 00000000..48bd1f7c --- /dev/null +++ b/tools/performance-tests/jmeter/DAP_Performance_Test.jmx @@ -0,0 +1,2464 @@ + + + + + + false + false + + + + + + + + + + host + conjur + = + Change this value to jmeter.apache.org + + + safecount + 500 + = + + + threadCount + 8 + = + + + server + dap + = + + + conjurAccount + demo + = + + + password + Basic YWRtaW46TXlTZWNyZXRQQHNzMQ== + = + + + key + null + = + + + + + + stoptest + + false + 1 + + 1 + 1 + false + + + true + + + + + + + true + + = + true + + + + ${server} + 443 + https + + /authn/${conjurAccount}/login + GET + true + false + true + false + + HttpClient4 + + + + + + + + Authorization + ${password} + + + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + groovy + + + true + vars.put("response", prev.getResponseDataAsString()); + + + + + + true + + + + false + ${response} + = + + + + ${server} + + https + + /authn/${conjurAccount}/admin/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; +log.info("response: " + vars.getObject("response")); +log.info("class: " + vars.getObject("response").getClass()); +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + + true + + + + false + - !group security_ops +- !group team_leads +- !group developers + +- !user + id: jason.vanderhoof + annotations: + first_name: Jason + last_name: Vanderhoof + email: jason.vanderhoof@cyberark.com + +- !user + id: marcel.calisto + annotations: + first_name: Marcel + last_name: Calisto + email: marcel.calisto@cyberark.com + +- !user + id: ernest.alvin + annotations: + first_name: Ernest + last_name: Alvin + email: ernest.alvin@cyberark.com + +- !user + id: victoria.nandita + annotations: + first_name: Victoria + last_name: Nandita + email: victoria.nandita@cyberark.com + +- !user + id: sophie.madelon + annotations: + first_name: Sophie + last_name: Madelon + email: sophie.madelon@cyberark.com + +- !user + id: terrance.blake + annotations: + first_name: Terrance + last_name: Blake + email: terrance.blake@cyberark.com + +- !grant + role: !group developers + members: + - !user marcel.calisto + - !user ernest.alvin + - !user sophie.madelon + +- !grant + role: !group team_leads + members: + - !user jason.vanderhoof + - !user victoria.nandita + +- !grant + role: !group security_ops + members: + - !user terrance.blake + +# Grant the less-powerful groups to the more-powerful groups +- !grant + member: !group team_leads + role: !group developers + +- !grant + member: !group security_ops + role: !group team_leads + = + + + + ${server} + 443 + https + + /policies/${conjurAccount}/policy/root + PUT + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:35:05.26213 + + + + + + Authorization + Token token="${token}" + + + + + + + true + + + + false + # Top-level policy file +- !group team_leads +- !group security_ops + +# Define "staging" namespace, owned by the "team_leads" +- !policy + id: staging + owner: !group team_leads + +# Define "production" namespace, owned by the "security_ops" team +- !policy + id: production + owner: !group security_ops + = + + + + ${server} + 443 + https + + /policies/${conjurAccount}/policy/root + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + + true + + + + false + - !policy + id: myapp + body: + - &variables + - !variable + id: database/url + annotations: + description: Database URL + - !variable + id: database/port + annotations: + description: Database port + - !variable + id: database/username + annotations: + description: Application database username + - !variable + id: database/password + annotations: + description: Application database password + - !layer + + - !host-factory + layer: [ !layer ] + + - !group secrets-users + - !group secrets-managers + + # secrets-users can read and execute + - !permit + resource: *variables + privileges: [ read, execute ] + role: !group secrets-users + + # secrets-managers can update (and read and execute, via role grant) + - !permit + resource: *variables + privileges: [ update ] + role: !group secrets-managers + + # secrets-managers has role secrets-users + - !grant + member: !group secrets-managers + role: !group secrets-users + + # Application layer has the secrets-users role + - !grant + member: !layer + role: !group secrets-users + = + + + + ${server} + 443 + https + + /policies/${conjurAccount}/policy/staging + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + + true + + + + false + - !policy + id: myapp + body: + - &variables + - !variable + id: database/url + annotations: + description: Database URL + - !variable + id: database/port + annotations: + description: Database port + - !variable + id: database/username + annotations: + description: Application database username + - !variable + id: database/password + annotations: + description: Application database password + - !layer + + - !group secrets-users + - !group secrets-managers + + # secrets-users can read and execute + - !permit + resource: *variables + privileges: [ read, execute ] + role: !group secrets-users + + # secrets-managers can update (and read and execute, via role grant) + - !permit + resource: *variables + privileges: [ update ] + role: !group secrets-managers + + # secrets-managers has role secrets-users + - !grant + member: !group secrets-managers + role: !group secrets-users + + # Application layer has the secrets-users role + - !grant + member: !layer + role: !group secrets-users + = + + + + ${server} + 443 + https + + /policies/${conjurAccount}/policy/production + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + + true + + + + false + # Grant the team_leads permission to read+write the "myapp" variables in production +- !grant + member: !group developers + role: !group staging/myapp/secrets-users + = + + + + ${server} + 443 + https + + /policies/${conjurAccount}/policy/root + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + + true + + + + false + - !host test-host-1 + +- !grant + role: !layer production/myapp + member: !host test-host-1 + = + + + + ${server} + 443 + https + + /policies/${conjurAccount}/policy/root + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + key + $.created_roles.demo:host:test-host-1.api_key + 1 + + + + groovy + + + true + import org.apache.jmeter.util.JMeterUtils; + +if(vars.getObject("key")){ + JMeterUtils.setProperty("key", vars.getObject("key")); + log.info("Set key property: " + vars.getObject("key")); +} + + + + + true + + + + false + alice + = + + + + ${server} + 443 + https + + /secrets/${conjurAccount}/variable/production/myapp/database/username + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + + true + + + + false + wonderland + = + + + + ${server} + 443 + https + + /secrets/${conjurAccount}/variable/production/myapp/database/password + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + + true + + + + false + https://oxfordshire.wonder.com + = + + + + ${server} + 443 + https + + /secrets/${conjurAccount}/variable/production/myapp/database/url + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + + true + + + + false + 1951 + = + + + + ${server} + 443 + https + + /secrets/${conjurAccount}/variable/production/myapp/database/port + POST + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + threadGroupMultiplier + + + + 1 + + + false + + + + true + + + + false + ${__P(key)} + = + + + + ${server} + + https + + authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + + groovy + + + + groovy + + + true + int loopSafeIterations = ${safecount} / ${threadCount}; + +vars.put("loopSafeIterations", loopSafeIterations.toString()); + + + + + true + ${loopSafeIterations} + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + (${DateNow}-${BaseDate})>360000 + false + + + + true + + + + false + ${__P(key)} + = + + + + ${server} + 443 + https + + /authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:33:44.235664 + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + + 1 + 500 + 1 + safeNum + + false + + + + true + 20 + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + + + + ${server} + 443 + https + + /secrets?variable_ids=demo:variable:production%2Fmyapp%2Fdatabase%2Fusername + GET + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + Created from cURL on 2019-12-26T16:35:05.262234 + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + threadGroupMultiplier + + + + 1 + + + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + + https + + authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + + groovy + + + + groovy + + + true + int loopSafeIterations = ${safecount} / ${threadCount}; + +vars.put("loopSafeIterations", loopSafeIterations.toString()); + + + + + true + ${loopSafeIterations} + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + (${DateNow}-${BaseDate})>360000 + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + 443 + https + + /authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:33:44.235664 + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + + 1 + 500 + 1 + safeNum + + false + + + + true + 20 + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + + + + ${server} + 443 + https + + /secrets?variable_ids=demo:variable:production%2Fmyapp%2Fdatabase%2Fusername + GET + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + Created from cURL on 2019-12-26T16:35:05.262234 + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + threadGroupMultiplier + + + + 1 + + + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + + https + + authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + + groovy + + + + groovy + + + true + int loopSafeIterations = ${safecount} / ${threadCount}; + +vars.put("loopSafeIterations", loopSafeIterations.toString()); + + + + + true + ${loopSafeIterations} + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + (${DateNow}-${BaseDate})>360000 + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + 443 + https + + /authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:33:44.235664 + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + + 1 + 500 + 1 + safeNum + + false + + + + true + 20 + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + + + + ${server} + 443 + https + + /secrets?variable_ids=demo:variable:production%2Fmyapp%2Fdatabase%2Fusername + GET + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + Created from cURL on 2019-12-26T16:35:05.262234 + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + threadGroupMultiplier + + + + 1 + + + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + + https + + authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + + groovy + + + + groovy + + + true + int loopSafeIterations = ${safecount} / ${threadCount}; + +vars.put("loopSafeIterations", loopSafeIterations.toString()); + + + + + true + ${loopSafeIterations} + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + (${DateNow}-${BaseDate})>360000 + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + 443 + https + + /authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:33:44.235664 + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + + 1 + 500 + 1 + safeNum + + false + + + + true + 20 + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + + + + ${server} + 443 + https + + /secrets?variable_ids=demo:variable:production%2Fmyapp%2Fdatabase%2Fusername + GET + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + Created from cURL on 2019-12-26T16:35:05.262234 + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + threadGroupMultiplier + + + + 1 + + + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + + https + + authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + + groovy + + + + groovy + + + true + int loopSafeIterations = ${safecount} / ${threadCount}; + +vars.put("loopSafeIterations", loopSafeIterations.toString()); + + + + + true + ${loopSafeIterations} + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + (${DateNow}-${BaseDate})>360000 + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + 443 + https + + /authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:33:44.235664 + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + + 1 + 500 + 1 + safeNum + + false + + + + true + 20 + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + + + + ${server} + 443 + https + + /secrets?variable_ids=demo:variable:production%2Fmyapp%2Fdatabase%2Fusername + GET + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + Created from cURL on 2019-12-26T16:35:05.262234 + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + threadGroupMultiplier + + + + 1 + + + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + + https + + authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + + groovy + + + + groovy + + + true + int loopSafeIterations = ${safecount} / ${threadCount}; + +vars.put("loopSafeIterations", loopSafeIterations.toString()); + + + + + true + ${loopSafeIterations} + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + (${DateNow}-${BaseDate})>360000 + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + 443 + https + + /authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:33:44.235664 + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + + 1 + 500 + 1 + safeNum + + false + + + + true + 20 + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + + + + ${server} + 443 + https + + /secrets?variable_ids=demo:variable:production%2Fmyapp%2Fdatabase%2Fusername + GET + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + Created from cURL on 2019-12-26T16:35:05.262234 + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + threadGroupMultiplier + + + + 1 + + + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + + https + + authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + + groovy + + + + groovy + + + true + int loopSafeIterations = ${safecount} / ${threadCount}; + +vars.put("loopSafeIterations", loopSafeIterations.toString()); + + + + + true + ${loopSafeIterations} + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + (${DateNow}-${BaseDate})>360000 + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + 443 + https + + /authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:33:44.235664 + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + + 1 + 500 + 1 + safeNum + + false + + + + true + 20 + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + + + + ${server} + 443 + https + + /secrets?variable_ids=demo:variable:production%2Fmyapp%2Fdatabase%2Fusername + GET + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + Created from cURL on 2019-12-26T16:35:05.262234 + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + threadGroupMultiplier + + + + 1 + + + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + + https + + authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + + groovy + + + + groovy + + + true + int loopSafeIterations = ${safecount} / ${threadCount}; + +vars.put("loopSafeIterations", loopSafeIterations.toString()); + + + + + true + ${loopSafeIterations} + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + (${DateNow}-${BaseDate})>360000 + false + + + + + + + false + ${__P(key)} + = + + + + true + ${server} + 443 + https + + /authn/${conjurAccount}/host%2Ftest-host-1/authenticate + POST + true + false + true + false + + HttpClient4 + + + Created from cURL on 2019-12-26T16:33:44.235664 + + + + true + + + import org.apache.commons.codec.binary.Base64; + +vars.put("token", Base64.encodeBase64String(prev.getResponseDataAsString().getBytes())); + groovy + + + + groovy + + + true + vars.put("BaseDate", new Date().getTime().toString()); + + + + + + 1 + 500 + 1 + safeNum + + false + + + + true + 20 + + + + groovy + + + true + vars.put("DateNow", new Date().getTime().toString()); + + + + + + + ${server} + 443 + https + + /secrets?variable_ids=demo:variable:production%2Fmyapp%2Fdatabase%2Fusername + GET + true + false + true + false + + + + + + + + + Authorization + Token token="${token}" + + + Created from cURL on 2019-12-26T16:35:05.262234 + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + /Users/hartzi/Desktop/DAP_Performance_Results.jtl + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + true + true + false + true + 0 + true + true + true + true + true + true + + + /Users/hartzi/Desktop/DAP_Performance_Results.jtl + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + true + false + true + 0 + true + true + true + true + true + true + + + + + + + + diff --git a/tools/simple-certificates/Dockerfile b/tools/simple-certificates/Dockerfile new file mode 100644 index 00000000..2f5e0621 --- /dev/null +++ b/tools/simple-certificates/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine:latest + +RUN apk add --no-cache bash \ + curl \ + openssl diff --git a/tools/simple-certificates/README.md b/tools/simple-certificates/README.md new file mode 100644 index 00000000..21dda1ab --- /dev/null +++ b/tools/simple-certificates/README.md @@ -0,0 +1,64 @@ +# Certificate Generator + +Creates certificates to mimic the PKI certificates a customer might find in their own environment. + +This script will generate: +- Root CA key/certificate +- Any intermediate CA key(s)/certificate(s), signed by the previous CA in the chain +- Conjur Node certificates, all signed by the Intermediate: + - `master-1.mycompany.local` + - `master-2.mycompany.local` + - `master-3.mycompany.local` + - `follower-1.mycompany.local` + - `follower-2.mycompany.local` + - You may override these leaf certificates with parameters from the CLI. + +### Generate +To create these certificates, navigate to this directory and run: +``` +$ ./generate_certificates [node_name...] +``` + +You can now use the following certificates to configure a Conjur cluster: +- `certificates/intermediate/cert/ca-chain.cert.pem` - CA Cert +- `certificates/nodes/master-1.mycompany.local/master-1.mycompany.local.cert.pem` - Master cert +- `certificates/nodes/master-1.mycompany.local/master-1.mycompany.local.key.pem` - Master key +- `certificates/nodes/follower-1.mycompany.local/follower-1.mycompany.local.cert.pem` - Follower 1 cert +- `certificates/nodes/follower-1.mycompany.local/follower-1.mycompany.local.key.pem` - Follower 1 key +- `certificates/nodes/follower-2.mycompany.local/follower-2.mycompany.local.cert.pem` - Follower 2 cert +- `certificates/nodes/follower-2.mycompany.local/follower-2.mycompany.local.key.pem` - Follower 2 key + +### Customizing + +#### Nodes + +Nodes can be changed with addition of the server names to the CLI args: +``` +$ ./generate_certificates 2 foo bar baz +``` + +This example will create the following certs: +- Root CA +- Intermediate CA Certs + - Intermediate 1 + - Intermediate 2 +- Leaf nodes + - foo.mycompany.local + - bar.mycompany.local + - baz.mycompany.local + +#### Domain name + +The domain can be customized by changing the following lines in `generate_certificates`: +``` +DOMAIN_NAME='mycompany.local' +``` + +Updating to the following: +``` +DOMAIN='cyberark.local' +``` +will produce signed certificates similar to these for the following domains: +- `master.cyberark.local` +- `follower1.cyberark.local` +- `follower2.cyberark.local` diff --git a/tools/simple-certificates/configs/openssl.cnf b/tools/simple-certificates/configs/openssl.cnf new file mode 100644 index 00000000..b10972c6 --- /dev/null +++ b/tools/simple-certificates/configs/openssl.cnf @@ -0,0 +1,131 @@ +[ ca ] +default_ca = CA_default + +[ CA_default ] +# Directory and file locations. +dir = /src/certificates/${ENV::SIGNER_NAME} +certs = $dir/certs +crl_dir = $dir/crl +new_certs_dir = $dir/newcerts +database = $dir/index.txt +serial = $dir/serial +RANDFILE = $dir/private/.rand + +# The root key and root certificate. +private_key = $dir/private/${ENV::SIGNER_NAME}.key.pem +certificate = $dir/certs/${ENV::SIGNER_NAME}.cert.pem + +# For certificate revocation lists. +crlnumber = $dir/crlnumber +crl = $dir/crl/${ENV::SIGNER_NAME}.crl.pem +crl_extensions = crl_ext +default_crl_days = 30 + +# SHA-1 is deprecated, so use SHA-2 instead. +default_md = sha256 + +name_opt = ca_default +cert_opt = ca_default +default_days = 365 +preserve = no +policy = policy_strict + +[ policy_strict ] +countryName = match +stateOrProvinceName = match +localityName = optional +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_loose ] +# Allow the intermediate CA to sign a more diverse range of certificates. +# See the POLICY FORMAT section of the `ca` man page. +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +# Options for the `req` tool (`man req`). +default_bits = 4096 +distinguished_name = req_distinguished_name +string_mask = utf8only + +# SHA-1 is deprecated, so use SHA-2 instead. +default_md = sha256 + +# Extension to add when the -x509 option is used. +x509_extensions = v3_ca + +[ req_distinguished_name ] +# See . +countryName = Country Name (2 letter code) +stateOrProvinceName = State or Province Name +localityName = Locality Name +0.organizationName = Organization Name +organizationalUnitName = Organizational Unit Name +commonName = Common Name +emailAddress = Email Address + +# Optionally, specify some defaults. +countryName_default = US +stateOrProvinceName_default = Massachusetts +localityName_default = Newton +0.organizationName_default = CyberArk +organizationalUnitName_default = Conjur +emailAddress_default = + +[ v3_ca ] +# Extensions for a typical CA (`man x509v3_config`). +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:TRUE +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ v3_intermediate_ca ] +# Extensions for a typical intermediate CA (`man x509v3_config`). +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +# We do not support generating chains longer than 20 intermediate CA +basicConstraints = critical, CA:TRUE, pathlen:20 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ usr_cert ] +# Extensions for client certificates (`man x509v3_config`). +basicConstraints = CA:FALSE +nsCertType = client, email +nsComment = "OpenSSL Generated Leaf Client Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, emailProtection + +[ server_cert ] +# Extensions for server certificates (`man x509v3_config`). +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Leaf Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + +[ crl_ext ] +# Extension for CRLs (`man x509v3_config`). +authorityKeyIdentifier=keyid:always + +[ ocsp ] +# Extension for OCSP signing certificates (`man ocsp`). +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, digitalSignature +extendedKeyUsage = critical, OCSPSigning + +[ san_env ] +subjectAltName=${ENV::SAN} diff --git a/tools/simple-certificates/generate_certificates b/tools/simple-certificates/generate_certificates new file mode 100755 index 00000000..59edd4b8 --- /dev/null +++ b/tools/simple-certificates/generate_certificates @@ -0,0 +1,308 @@ +#!/bin/bash -e + +DOMAIN_NAME='mycompany.local' + +DEFAULT_NODES=( 'conjur-master-1' + 'conjur-master-2' + 'conjur-master-3' + 'follower-1' + 'follower-2' ) + +CERT_PASSWORD='secret' + +IMAGE_TAG='conjurinc-certgen' + +REQUIRED_DIRS=( 'certs' + 'crl' + 'csr' + 'newcerts' + 'private' ) + +RSA_KEY_LENGTH=4096 + +BASE_PATH='certificates' +BASE_ROOT_CERT_PATH="${BASE_PATH}/root" +BASE_NODE_CERT_PATH="${BASE_PATH}/nodes" + +CURRENT_DIR="$(pwd)" + +if [[ "$#" -lt 1 ]]; then + echo "Usage: $0 [node_name...]" + exit 1 +fi + +# Grab the cert depth level from CLI args +INTERMEDIATE_CERT_DEPTH="${1}" +shift +echo "Trying to generate certs with ${INTERMEDIATE_CERT_DEPTH} intermediate CAs" + +# Grab the node names from CLI args if they were specified +leaf_nodes="${DEFAULT_NODES[@]}" +if [[ "$#" -gt 0 ]]; then + leaf_nodes="$@" +fi +echo "Leaf nodes: $leaf_nodes" + +first_leaf_node="${leaf_nodes[0]}" +if [[ "${first_leaf_node}" != "${first_leaf_node%%.*}" ]]; then + DOMAIN_NAME="${first_leaf_node#*.}" + echo "Domain name detected: ${DOMAIN_NAME}" + + new_leaf_nodes="" + for leaf_node in "${leaf_nodes}"; do + new_leaf_nodes+=" ${leaf_nodes%%.*}" + done + leaf_nodes="${new_leaf_nodes}" + echo "Leaf nodes: $leaf_nodes" +fi + +echo "**************************************************" +echo "Building our SSL docker image..." +docker build -t "${IMAGE_TAG}" . + +alt_names="" +for node_name in ${leaf_nodes}; do + alt_names+="DNS:${node_name}.${DOMAIN_NAME}," +done + +# Trim last character (comma) +alt_names="${alt_names%?}" + +san="" +signer_name="" + +function ssl_proxy { + local work_dir="$1" + shift + + local cmd="$@" + + if [ "${DEBUG}" == "true" ]; then + set -x + fi + + docker run -it \ + --rm \ + -v "${CURRENT_DIR}:/src" \ + -v "${CURRENT_DIR}/configs:/configs" \ + -w "/src/${work_dir}" \ + -e "SAN=${san}" \ + -e "SIGNER_NAME=${signer_name}" \ + "${IMAGE_TAG}" bash -c " + $cmd + " + + if [ "${DEBUG}" == "true" ]; then + set +x + fi + +} + +signer_name="root" +if [ ! -f "${BASE_ROOT_CERT_PATH}/certs/root.cert.pem" ]; then + echo "**************************************************" + echo "CA cert not found. Regenerating CA..." + + echo "Performing some housekeeping for CA..." + for ca_dir in ${REQUIRED_DIRS[@]}; do + ca_dir_path="${BASE_ROOT_CERT_PATH}/${ca_dir}" + mkdir -p "${ca_dir_path}" + done + + chmod 700 "${BASE_ROOT_CERT_PATH}/private" + touch "${BASE_ROOT_CERT_PATH}/index.txt" + echo 1000 > "${BASE_ROOT_CERT_PATH}/serial" + + echo "Generating root CA RSA key..." + ssl_proxy "${BASE_ROOT_CERT_PATH}" \ + openssl genrsa -aes256 \ + -passout "pass:$CERT_PASSWORD" \ + -out "private/root.key.pem" \ + "${RSA_KEY_LENGTH}" + ssl_proxy "${BASE_ROOT_CERT_PATH}" chmod 400 "private/root.key.pem" + + echo "Generating root CA certificate from the RSA key..." + ssl_proxy "${BASE_ROOT_CERT_PATH}" \ + openssl req -config "/configs/openssl.cnf" \ + -passout "pass:$CERT_PASSWORD" \ + -passin "pass:$CERT_PASSWORD" \ + -subj "\"/C=US/ST=Massachusetts/O=CyberArk/OU=Conjur/CN=Root CA\"" \ + -key "private/root.key.pem" \ + -new -x509 -days 7300 -sha256 -extensions v3_ca \ + -out "certs/root.cert.pem" + + ssl_proxy "${BASE_ROOT_CERT_PATH}" chmod 444 "certs/root.cert.pem" + + if [ "${DEBUG}" == "true" ]; then + ssl_proxy "${BASE_ROOT_CERT_PATH}" openssl x509 -noout -text -in "certs/root.cert.pem" + fi +fi + +echo "**************************************************" + +for intermediate_cert_index in $(seq 1 ${INTERMEDIATE_CERT_DEPTH}); do + intermediate_cert_name="intermediate_${intermediate_cert_index}" + intermediate_cert_cn="Intermediate CA ${intermediate_cert_index}" + intermediate_cert_file="${intermediate_cert_name}.cert.pem" + intermediate_key_file="${intermediate_cert_name}.key.pem" + intermediate_csr_file="${intermediate_cert_name}.csr.pem" + + intermediate_ca_path="${BASE_PATH}/${intermediate_cert_name}" + + if [[ ! -f "${CURRENT_DIR}/${intermediate_ca_path}" ]]; then + echo "Performing some housekeeping for intermediate CA..." + for ca_dir in ${REQUIRED_DIRS[@]}; do + ca_dir_path="${intermediate_ca_path}/${ca_dir}" + mkdir -p "${ca_dir_path}" + done + + chmod 700 "${intermediate_ca_path}/private" + touch "${intermediate_ca_path}/index.txt" + echo 1000 > "${intermediate_ca_path}/crlnumber" + echo 1000 > "${intermediate_ca_path}/serial" + fi + + echo "Checking intermediate cert number ${intermediate_cert_index}..." + if [ ! -f "${intermediate_ca_path}/certs/${intermediate_cert_file}" ]; then + echo "Intermediate cert '${intermediate_cert_name}' not found. Regenerating..." + + echo "Generating intermediate RSA key (${intermediate_cert_name})..." + ssl_proxy "${intermediate_ca_path}" \ + openssl genrsa -aes256 \ + -passout "pass:${CERT_PASSWORD}" \ + -out "private/${intermediate_key_file}" \ + "${RSA_KEY_LENGTH}" + ssl_proxy "${intermediate_ca_path}" chmod 400 "private/${intermediate_key_file}" + + echo "Generating intermediate CSR (${intermediate_cert_name}) from the RSA key..." + signer_name="${intermediate_cert_name}" + ssl_proxy "${intermediate_ca_path}" \ + openssl req -config "/configs/openssl.cnf" \ + -new -sha256 \ + -passout "pass:${CERT_PASSWORD}" \ + -passin "pass:${CERT_PASSWORD}" \ + -subj "\"/C=US/ST=Massachusetts/L=Newton/O=CyberArk/OU=Conjur/CN=${intermediate_cert_cn}\"" \ + -key "private/${intermediate_key_file}" \ + -out "csr/${intermediate_csr_file}" + + skip_cert_chain="false" + signer_name="intermediate_$(( intermediate_cert_index - 1 ))" + if [[ "${intermediate_cert_index}" == "1" ]]; then + echo "First intermediate cert detected. Signing with root key." + skip_cert_chain="true" + signer_name="root" + fi + + echo "Using signer cert '${signer_name}'" + + echo "Creating a parent CA-signed intermediate cert (${intermediate_cert_name}) from the CSR..." + ssl_proxy "${intermediate_ca_path}" \ + openssl ca -config "/configs/openssl.cnf" \ + -extensions v3_intermediate_ca \ + -days 3650 -notext -md sha256 -batch \ + -passin "pass:${CERT_PASSWORD}" \ + -in "csr/${intermediate_csr_file}" \ + -out "certs/${intermediate_cert_file}" + + ssl_proxy "${intermediate_ca_path}" chmod 444 "certs/${intermediate_cert_file}" + + if [ "${DEBUG}" == "true" ]; then + ssl_proxy "${intermediate_ca_path}" openssl x509 -noout -text \ + -in "certs/${intermediate_cert_file}" + fi + + echo "Building cert chain list for verification..." + untrusted_certs_params="" + if [ "${skip_cert_chain}" != "true" ]; then + untrusted_certs_file="${BASE_PATH}/intermediate_${intermediate_cert_index}/rootless-ca-chain.cert.pem" + for cert_chain_index in $( seq 1 $((${intermediate_cert_index} - 1)) ); do + cert_path="${CURRENT_DIR}/${BASE_PATH}/intermediate_${cert_chain_index}/certs/intermediate_${cert_chain_index}.cert.pem" + cat "${cert_path}" >> "${CURRENT_DIR}/${untrusted_certs_file}" + done + untrusted_certs_params="-untrusted /src/${untrusted_certs_file}" + fi + + echo "Validating that the generated cert (${intermediate_cert_name}) is signed with the right CA key..." + ssl_proxy "${intermediate_ca_path}" \ + openssl verify -CAfile "/src/certificates/root/certs/root.cert.pem" \ + ${untrusted_certs_params} \ + "/src/${intermediate_ca_path}/certs/${intermediate_cert_file}" + fi +done + +echo "Building the complete cert chain..." +cert_chain_files="" +for intermediate_cert_index in $(seq ${INTERMEDIATE_CERT_DEPTH} 1); do + intermediate_cert_name="intermediate_${intermediate_cert_index}" + intermediate_cert_file="${intermediate_cert_name}.cert.pem" + + cert_chain_files+=" ${CURRENT_DIR}/certificates/${intermediate_cert_name}/certs/${intermediate_cert_file}" +done +cert_chain_files+=" ${CURRENT_DIR}/certificates/root/certs/root.cert.pem" + +echo "Creating the complete cert chain file..." +if [ "${DEBUG}" == "true" ]; then + echo "Cert chain:${cert_chain_files}" +fi +cat ${cert_chain_files} > "${CURRENT_DIR}/certificates/ca-chain.cert.pem" + + +echo "**************************************************" +echo "Generating node certificates..." + +for node_name in ${leaf_nodes}; do + node_fqdn="${node_name}.${DOMAIN_NAME}" + node_cert_folder="${BASE_NODE_CERT_PATH}/${node_fqdn}" + node_cert_file="${node_cert_folder}/${node_fqdn}.cert.pem" + node_key_file="${node_cert_folder}/${node_fqdn}.key.pem" + node_csr_file="${node_cert_folder}/${node_fqdn}.csr.pem" + + echo "Checking '${node_fqdn}' cert..." + if [ ! -f "$node_cert_folder/$node_fqdn.cert.pem" ]; then + echo "Node '$node_fqdn' cert missing. Regenerating..." + mkdir -p "${CURRENT_DIR}/$node_cert_folder" + + echo "Generating node RSA keypair..." + ssl_proxy "." openssl genrsa -out "/src/${node_key_file}" "${RSA_KEY_LENGTH}" + + echo "Creating the leaf CSR from RSA key..." + san="DNS:${node_name},${alt_names}" + # CN cannot be >64chars. https://github.com/certbot/certbot/issues/1915#issuecomment-165262834 + node_cn="${node_fqdn%%.*}" + signer_name="intermediate_${INTERMEDIATE_CERT_DEPTH}" + ssl_proxy "." openssl req -config "/configs/openssl.cnf" \ + -subj "\"/C=US/ST=Massachusetts/L=Newton/O=CyberArk/OU=Conjur/CN=${node_cn}\"" \ + -extensions san_env \ + -key "/src/${node_key_file}" \ + -new -sha256 -out "/src/${node_csr_file}" + + echo "Signing leaf node with the intermediate cert..." + ssl_proxy "." openssl ca -config "/configs/openssl.cnf" \ + -extensions server_cert -days 365 -notext -md sha256 -batch \ + -passin "pass:${CERT_PASSWORD}" \ + -extensions san_env \ + -in "/src/${node_csr_file}" \ + -out "/src/${node_cert_file}" + chmod 444 "${CURRENT_DIR}/${node_cert_file}" + + if [ "${DEBUG}" == "true" ]; then + ssl_proxy "." \ + openssl x509 -noout -text -in "/src/${node_cert_file}" + fi + + chmod 400 "${CURRENT_DIR}/${node_key_file}" + fi +done + +# Some of this code is repetitive but it allows for easier visibility +# that all the certs are properly validated at the end of the run +echo "**************************************************" +echo "Validating that the generated node certs are properly signed..." +for node_name in ${leaf_nodes}; do + node_fqdn="${node_name}.${DOMAIN_NAME}" + node_cert_folder="${BASE_NODE_CERT_PATH}/${node_fqdn}" + node_cert_file="${node_cert_folder}/${node_fqdn}.cert.pem" + ssl_proxy "." \ + openssl verify -CAfile "/src/certificates/ca-chain.cert.pem" \ + "${node_cert_file}" +done diff --git a/tools/simple-policy-test-v5/README.md b/tools/simple-policy-test-v5/README.md new file mode 100644 index 00000000..fef9cf8a --- /dev/null +++ b/tools/simple-policy-test-v5/README.md @@ -0,0 +1,20 @@ +# Simple policy and value setter/getter + +Loads a policy into a Conjur instance, sets the value of it, and then runs a watch on its value. + +### Usage + +To run this script, all you need to do is run the `apply-and-watch` script: +``` +$ ./apply-and-watch [] +``` + +Example with both master and follower: +``` +$ ./apply-and-watch master.myorg.com demo supersecretapikey follower.myorg.com +``` + +Example with no follower: +``` +$ ./apply-and-watch master.myorg.com demo supersecretapikey +``` diff --git a/tools/simple-policy-test-v5/apply-and-watch b/tools/simple-policy-test-v5/apply-and-watch new file mode 100755 index 00000000..b5031fe3 --- /dev/null +++ b/tools/simple-policy-test-v5/apply-and-watch @@ -0,0 +1,29 @@ +#!/bin/bash -e + +if [ "$#" -lt 3 ]; then + echo "ERROR: Usage: '$0 []'" + exit 1 +fi + +export MASTER_HOSTNAME="$1" +export ACCOUNT="$2" +export ADMIN_API_KEY="$3" +export FOLLOWER_HOSTNAME="$4" + +MOUNT_POINT=/tmp/data + +# This must match the policy document +CREDENTIAL_ID="test-password" + +CLI_CMD="$MOUNT_POINT/save-and-watch $MOUNT_POINT/policy.yml ${CREDENTIAL_ID} test-password-value" + +set -x +docker run --rm \ + -it \ + -v "$(pwd)/cli_files:$MOUNT_POINT" \ + -e MASTER_HOSTNAME \ + -e FOLLOWER_HOSTNAME \ + -e ACCOUNT \ + -e ADMIN_API_KEY \ + --entrypoint bash \ + cyberark/conjur-cli:5 -c "$CLI_CMD" diff --git a/tools/simple-policy-test-v5/cli_files/policy.yml b/tools/simple-policy-test-v5/cli_files/policy.yml new file mode 100644 index 00000000..9256f39b --- /dev/null +++ b/tools/simple-policy-test-v5/cli_files/policy.yml @@ -0,0 +1,5 @@ +--- +- !variable + id: test-password + annotations: + mime_type: text/plain diff --git a/tools/simple-policy-test-v5/cli_files/save-and-watch b/tools/simple-policy-test-v5/cli_files/save-and-watch new file mode 100755 index 00000000..43a01638 --- /dev/null +++ b/tools/simple-policy-test-v5/cli_files/save-and-watch @@ -0,0 +1,61 @@ +#!/bin/bash -eu + +set -o pipefail + +USAGE="Usage: $0 " + +if [ "$MASTER_HOSTNAME" == "" ]; then + echo "ERROR: MASTER_HOSTNAME not defined!" + exit 1 +fi + +if [ "$ACCOUNT" == "" ]; then + echo "ERROR: ACCOUNT not defined!" + exit 1 +fi + +if [ "$ADMIN_API_KEY" == "" ]; then + echo "ERROR: ADMIN_API_KEY not defined!" + exit 1 +fi + +if [ $# -lt 3 ]; then + echo "ERROR: $USAGE" + exit 1 +fi + +POLICY_PATH="$1" +CREDENTIAL_ID="$2" +CREDENTIAL_VALUE="$3" + +conjur_login() { + local HOSTNAME="$1" + echo "Initializing CLI ($ACCOUNT@https://$HOSTNAME)..." + + echo "yes" | conjur init --force=yes \ + -u "https://$HOSTNAME" \ + -a "$ACCOUNT" + + echo "Logging in..." + conjur authn login -u admin -p "$ADMIN_API_KEY" + conjur authn whoami +} + +conjur_login "$MASTER_HOSTNAME" +echo "Loading policy..." +conjur policy load --replace root "$1" + +echo "Persisting variable value ('$CREDENTIAL_VALUE' -> $CREDENTIAL_ID)..." +conjur variable values add "$CREDENTIAL_ID" "$CREDENTIAL_VALUE" + +echo "Credential $CREDENTIAL_ID set to $CREDENTIAL_VALUE!" + +if [[ "$FOLLOWER_HOSTNAME" != "" ]]; then + conjur_login "$FOLLOWER_HOSTNAME" +fi + +echo "Fetching value ($CREDENTIAL_ID)..." +while true; do + echo $(date): $(conjur variable value "$CREDENTIAL_ID") + sleep 2 +done diff --git a/vm/Vagrantfile b/vm/Vagrantfile new file mode 100644 index 00000000..8378ce3c --- /dev/null +++ b/vm/Vagrantfile @@ -0,0 +1,70 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + # Every Vagrant development environment requires a box. You can search for + # boxes at https://vagrantcloud.com/search. + config.vm.box = "centos/7" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # NOTE: This will enable public access to the opened port + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine and only allow access + # via 127.0.0.1 to disable public access + # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider "virtualbox" do |vb| + # # Display the VirtualBox GUI when booting the machine + # vb.gui = true + # + # # Customize the amount of memory on the VM: + # vb.memory = "1024" + # end + # + # View the documentation for the provider you are using for more + # information on available options. + + # Enable provisioning with a shell script. Additional provisioners such as + # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the + # documentation for more information about their specific syntax and use. + # config.vm.provision "shell", inline: <<-SHELL + # apt-get update + # apt-get install -y apache2 + # SHELL +end