63 lines
1.6 KiB
Ruby
Executable file
63 lines
1.6 KiB
Ruby
Executable file
#!/usr/bin/env ruby
|
|
|
|
require 'pathname'
|
|
require 'lxc'
|
|
require 'etc'
|
|
|
|
require_relative 'ns'
|
|
require_relative 'cborio'
|
|
require_relative 'lxc_extend'
|
|
require_relative 'authorized_keys'
|
|
|
|
class AuthorizedKeysCollector
|
|
def initialize
|
|
end
|
|
|
|
def forked wr
|
|
LXC.running_containers do |ct|
|
|
pid = ct.init_pid
|
|
NS.change pid, :pid, :mnt do
|
|
name = ct.config_item( 'lxc.uts.name')
|
|
conf = Hash.new {|h,k| h[k] = []}
|
|
IO.popen %w[sshd -T], err: "/dev/null" do |s|
|
|
s.each_line do |l|
|
|
k, v = l.chomp.split( ' ', 2)
|
|
conf[k.to_sym].push v
|
|
end
|
|
end
|
|
akf = conf[:authorizedkeysfile].flat_map {|e| e.split ' ' }
|
|
akf.map! do |pn|
|
|
pn = "%h/#{pn}" if Pathname.new( pn).relative?
|
|
pn.gsub( /%h/, "%<home>s").gsub( /%u/, "%<name>s")
|
|
end
|
|
while pw = Etc.getpwent
|
|
wr.write [
|
|
:authkeys, ct.name, pw.name,
|
|
akf.each.flat_map do |pn|
|
|
pn = Pathname.new pn % {name: pw.name, home: pw.dir}
|
|
pn.exist? ? pn.readlines.map( &:chomp) : []
|
|
end
|
|
]
|
|
end
|
|
Etc.endpwent
|
|
end
|
|
end
|
|
end
|
|
|
|
def collect
|
|
pid, io = CBORIO.popen {|io| forked io }
|
|
io.map do |l|
|
|
case l[0].to_sym
|
|
when :authkeys
|
|
host, user, keys = l[1..3]
|
|
keys.map! {|k| AuthorizedKeys.parse k }
|
|
{host: host, user: user, keys: keys}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if Pathname.new( __FILE__).expand_path == Pathname.new( $0).expand_path
|
|
AuthorizedKeysCollector.new.collect.each {|e| p e }
|
|
end
|