python - Cambiando la configuración de DNS usando PyObjC
macos (1)
Estoy tratando de cambiar los servidores DNS en mi Mac (10.10.4) usando PyObjC (3.0.4).
Todo parece funcionar: aparece un cuadro de diálogo de autenticación que indica que mi programa está intentando cambiar la configuración de la red y que los comandos de confirmación / aplicación devuelven el valor True
, lo que indicaría que tuvieron éxito.
Sin embargo, la configuración del sistema no se cambia realmente: siguen siendo las mismas que antes. ¿Alguna idea de por qué no se "pegan"?
El código (independiente, debería funcionar si tiene instalada una versión reciente de PyObjC):
#!/usr/bin/env python
import objc
from SystemConfiguration import *
# Open dynamic store and get primary interface
store = SCDynamicStoreCreate(None, ''MyApp'', None, None)
primaryif = SCDynamicStoreCopyValue(store, ''State:/Network/Global/IPv4'')[''PrimaryInterface'']
if primaryif:
print "Using %s as primary interface" % primaryif
else:
raise "Can''t find primary interface"
# Load SecurityInterface framework to provide SFAuthorization
objc.initFrameworkWrapper(
frameworkName = "SecurityInterface",
frameworkIdentifier = "com.apple.securityinterface",
frameworkPath = objc.pathForFramework("/System/Library/Frameworks/SecurityInterface.framework"),
globals = globals()
)
# Access system preferences
preferences = SCPreferencesCreateWithAuthorization(None, ''MyApp'', None, SFAuthorization.authorization().authorizationRef())
# Lock preferences
SCPreferencesLock(preferences, True)
# Get list of network services
networkSet = SCNetworkSetCopyCurrent(preferences)
networkSetServices = SCNetworkSetCopyServices(networkSet)
# Find the network service that belongs to the primary interface
for networkService in networkSetServices:
interface = SCNetworkServiceGetInterface(networkService)
if primaryif != SCNetworkInterfaceGetBSDName(interface):
continue
# Load currently configured DNS servers
networkProtocol = SCNetworkServiceCopyProtocol(networkService, kSCNetworkProtocolTypeDNS)
DNSDict = SCNetworkProtocolGetConfiguration(networkProtocol) or {}
# Set new DNS servers
DNSDict[kSCPropNetDNSServerAddresses] = [ ''192.168.23.12'', ''8.8.4.4'' ]
SCNetworkProtocolSetConfiguration(networkService, DNSDict)
# Unlock, commit and apply preferences
print "UL", SCPreferencesUnlock(preferences)
print "CO", SCPreferencesCommitChanges(preferences)
print "AP", SCPreferencesApplyChanges(preferences)
EDITAR : la mayor parte del código anterior se basa en esta página , que también sugiere "tocar" el almacenamiento dinámico para que los ajustes se mantengan (el código para hacer esto se comenta al final). Sin embargo, no parece hacer nada.
EDIT # 2 : al desensamblar /usr/sbin/networksetup
Tengo la idea de que necesito un conjunto de derechos específicos ( system.services.systemconfiguration.network
) antes de que se acepte cualquier cambio.
Parece que hay problemas con PyObjC que hacen que esto no funcione, sin embargo, es posible que pueda encontrar una forma de evitarlo utilizando una solución diferente. Si fuera usted, y mi situación lo permitiera, solo llamaría a las herramientas de línea de comandos del sistema para configurar los servidores DNS.
Según OSXDaily , puedes hacer esto con:
networksetup -setdnsservers (Network Service) (DNS IP)
Si tiene requisitos de plataforma cruzada, esto obviamente es menos que deseable.