├── .gitignore ├── CODE_OF_CONDUCT.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── lib ├── vagrant-trellis-cert.rb └── vagrant_plugins │ └── trellis_cert │ ├── certificate.rb │ ├── command │ ├── distrust.rb │ ├── root.rb │ └── trust.rb │ ├── config.rb │ ├── identity.rb │ ├── plugin.rb │ ├── result.rb │ └── ssl_config.rb └── vagrant-trellis-cert.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | 11 | .rbenv-gemsets 12 | .ruby-version 13 | /.gems/ 14 | /vagrant-trellis-cert-*.gem 15 | .rubocop-http* 16 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at vagrant-trellis-cert@typist.tech. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } 5 | 6 | # To make `$ bundle exec vagrant` works 7 | embedded_directories = %w[/Applications/Vagrant/embedded /opt/vagrant/embedded] 8 | embedded_directories.each do |path| 9 | ENV['VAGRANT_INSTALLER_EMBEDDED_DIR'] = path if File.directory?(path) 10 | end 11 | 12 | unless ENV.key?('VAGRANT_INSTALLER_EMBEDDED_DIR') 13 | $stderr.puts "Couldn't find a packaged install of vagrant, and we need this" 14 | $stderr.puts 'in order to make use of the RubyEncoder libraries.' 15 | $stderr.puts 'I looked in:' 16 | embedded_directories.each do |path| 17 | $stderr.puts " #{path}" 18 | end 19 | end 20 | 21 | group :development do 22 | # We depend on Vagrant for development, but we don't add it as a 23 | # gem dependency because we expect to be installed within the 24 | # Vagrant environment itself using `vagrant plugin`. 25 | gem 'vagrant', github: 'hashicorp/vagrant' 26 | end 27 | 28 | group :plugins do 29 | gemspec 30 | end 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2020 Typist Tech 4 | Copyright (c) 2017-2020 Tang Rufus 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
18 | Trust Trellis self-signed certificates with a single command
19 |
20 |
21 | Built with ♥ by Typist Tech
22 |
65 | Typist Tech is ready to build your next awesome WordPress site. Hire us! 66 |
67 | 68 | --- 69 | 70 | ## Minimum Requirements 71 | 72 | - macOS 10.13.3 73 | - Vagrant 2.0.3 74 | 75 | ## Installation 76 | 77 | ```sh-session 78 | $ vagrant plugin install vagrant-trellis-cert 79 | ``` 80 | 81 | ## FAQs 82 | 83 | ### What to do when `getaddrinfo: nodename nor servname provided, or not known` 84 | 85 | Make sure your hosts file (`/etc/hosts`) contains all the domains you're self-signing. 86 | 87 | Usually it can be rectified by `$ vagrant reload --provision` or `$ vagrant hostmanager`. 88 | 89 | Ask on [Root Discourse](https://discourse.roots.io/) if the problem persists. 90 | 91 | ### It looks awesome. Where can I find some more goodies like this 92 | 93 | - Articles on [Typist Tech's blog](https://typist.tech) 94 | - [Tang Rufus' WordPress plugins](https://profiles.wordpress.org/tangrufus#content-plugins) on wp.org 95 | - More projects on [Typist Tech's GitHub profile](https://github.com/TypistTech) 96 | - Stay tuned on [Typist Tech's newsletter](https://typist.tech/go/newsletter) 97 | - Follow [Tang Rufus' Twitter account](https://twitter.com/TangRufus) 98 | - **Hire [Tang Rufus](https://typist.tech/contact) to build your next awesome site** 99 | 100 | ### Where can I give 5-star reviews? 101 | 102 | Thanks! Glad you like it. It's important to let me knows somebody is using this project. Please consider: 103 | 104 | - [tweet](https://twitter.com/intent/tweet?text=Vagrant%20Trellis%20Cert%20-%20Trust%20Trellis%20self-signed%20certificates%20with%20a%20single%20command&url=https://github.com/TypistTech/vagrant-trellis-cert&hashtags=webdev,wordpress&via=TangRufus&url=https://github.com/TypistTech/vagrant-trellis-cert&hashtags=webdev,wordpress&via=TangRufus) something good with mentioning [@TangRufus](https://twitter.com/tangrufus) 105 | - ★ star [the Github repo](https://github.com/TypistTech/vagrant-trellis-cert) 106 | - [👀 watch](https://github.com/TypistTech/vagrant-trellis-cert/subscription) the Github repo 107 | - write tutorials and blog posts 108 | - **[hire](https://www.typist.tech/contact/) Typist Tech** 109 | 110 | ## Feedback 111 | 112 | **Please provide feedback!** We want to make this project as useful as possible. 113 | Please [submit an issue](https://github.com/TypistTech/vagrant-trellis-cert/issues/new) and point out what you do and don't like, or fork the project and [send pull requests](https://github.com/TypistTech/vagrant-trellis-cert/pulls/). 114 | **No issue is too small.** 115 | 116 | ## Security Vulnerabilities 117 | 118 | If you discover a security vulnerability within this project, please email us at [vagrant-trellis-cert@typist.tech](mailto:vagrant-trellis-cert@typist.tech). 119 | All security vulnerabilities will be promptly addressed. 120 | 121 | ## Credits 122 | 123 | [Vagrant Trellis Cert](https://github.com/TypistTech/vagrant-trellis-cert) is a [Typist Tech](https://www.typist.tech) project and maintained by [Tang Rufus](https://twitter.com/Tangrufus), freelance developer for [hire](https://www.typist.tech/contact/). 124 | 125 | Special thanks to [the Roots team](https://roots.io/about/) whose [Trellis](https://github.com/roots/trellis) make this project possible. 126 | 127 | Full list of contributors can be found [here](https://github.com/TypistTech/vagrant-trellis-cert/graphs/contributors). 128 | 129 | ## License 130 | 131 | [Vagrant Trellis Cert](https://github.com/TypistTech/vagrant-trellis-cert) is released under the [MIT License](https://opensource.org/licenses/MIT). 132 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/gem_tasks' 4 | -------------------------------------------------------------------------------- /lib/vagrant-trellis-cert.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | begin 4 | require 'vagrant' 5 | rescue LoadError 6 | raise 'The Vagrant Trellis Cert plugin must be run within Vagrant.' 7 | end 8 | 9 | # This is a sanity check to make sure no one is attempting to install 10 | # this into an early Vagrant version. 11 | # Requiring 2.0.3 or later because of Ruby 2.4.2 12 | if Vagrant::VERSION < '2.0.3' 13 | raise 'The Vagrant Trellis Cert plugin is only compatible with Vagrant 2.0.3 or later' 14 | end 15 | 16 | require 'vagrant_plugins/trellis_cert/identity' 17 | require 'vagrant_plugins/trellis_cert/plugin' 18 | -------------------------------------------------------------------------------- /lib/vagrant_plugins/trellis_cert/certificate.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'socket' 4 | require 'openssl' 5 | 6 | module VagrantPlugins 7 | module TrellisCert 8 | class Certificate 9 | def initialize(host:, tmp_dir:) 10 | @host = host 11 | @tmp_dir = tmp_dir 12 | end 13 | 14 | def download 15 | fetch 16 | 17 | File.open(path, 'w') do |file| 18 | file.write(@cert.to_der) 19 | end 20 | end 21 | 22 | def path 23 | "#{@tmp_dir}/#{@host}.der" 24 | end 25 | 26 | private 27 | 28 | def fetch 29 | tcp_client = TCPSocket.new(@host, 443) 30 | ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client) 31 | ssl_client.hostname = @host 32 | ssl_client.connect 33 | @cert = OpenSSL::X509::Certificate.new(ssl_client.peer_cert) 34 | ensure 35 | ssl_client&.sysclose 36 | tcp_client&.close 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/vagrant_plugins/trellis_cert/command/distrust.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'vagrant_plugins/trellis_cert/ssl_config' 4 | require 'vagrant_plugins/trellis_cert/result' 5 | 6 | module VagrantPlugins 7 | module TrellisCert 8 | module Command 9 | class Distrust < Vagrant.plugin('2', :command) 10 | KEYCHAIN = '~/Library/Keychains/login.keychain' 11 | 12 | def execute 13 | _options, argv = parse_options! 14 | 15 | @env.ui.info('Removing certificates...') 16 | 17 | ssl_config = SSLConfig.new(root_path: machine_root_path(argv)) 18 | 19 | result = distrust(ssl_config.canonicals) 20 | 21 | result.print(ui: @env.ui) 22 | 23 | result.exit_code 24 | end 25 | 26 | private 27 | 28 | def parse_options! 29 | options = {} 30 | opts = OptionParser.new do |o| 31 | o.banner = 'Usage: vagrant trellis-cert distrust [options] [vm-id]' 32 | o.separator '' 33 | 34 | o.on('-h', '--help', 'Print this help') do 35 | @env.ui.info(opts) 36 | exit 37 | end 38 | end 39 | [options, parse_options(opts)] 40 | end 41 | 42 | def machine_root_path(argv) 43 | with_target_vms(argv) do |machine| 44 | return machine.env.root_path 45 | end 46 | end 47 | 48 | def distrust(hosts) 49 | Result.new.tap do |result| 50 | hosts.map do |host| 51 | is_success = system("security delete-certificate -c #{host} #{KEYCHAIN} >/dev/null 2>/dev/null") 52 | 53 | result.add(host: host, is_success: is_success) 54 | end 55 | end 56 | end 57 | end 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/vagrant_plugins/trellis_cert/command/root.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'optparse' 4 | 5 | module VagrantPlugins 6 | module TrellisCert 7 | module Command 8 | class Root < Vagrant.plugin('2', :command) 9 | def self.synopsis 10 | 'trust Trellis self-signed certificates' 11 | end 12 | 13 | def initialize(argv, env) 14 | super 15 | 16 | @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv) 17 | 18 | @subcommands = Vagrant::Registry.new 19 | 20 | @subcommands.register(:trust) do 21 | require_relative 'trust' 22 | Trust 23 | end 24 | 25 | @subcommands.register(:distrust) do 26 | require_relative 'distrust' 27 | Distrust 28 | end 29 | end 30 | 31 | def execute 32 | return help if help? || !sub_command? 33 | 34 | # Initialize and execute the command class 35 | @subcommands.get(@sub_command&.to_sym) 36 | .new(@sub_args, @env) 37 | .execute 38 | rescue Vagrant::Errors::VagrantError => e 39 | raise e 40 | rescue StandardError => e 41 | raise Vagrant::Errors::CLIInvalidUsage, help: "#{e.message}\r\n\r\nBacktrace:\r\n#{e.backtrace&.join("\r\n")}" 42 | end 43 | 44 | private 45 | 46 | def help? 47 | (@main_args & %w[-h --help]).any? 48 | end 49 | 50 | def sub_command? 51 | @subcommands.key?(@sub_command&.to_sym) 52 | end 53 | 54 | def help 55 | option_parser = OptionParser.new do |opts| 56 | opts.banner = 'Usage: vagrant trellis-cert