Para criar novos usuários no MySQL 5 sem utilizar uma ferramenta auxiliar como o phpMyAdmin é necessário conhecer o statement GRANT
, mas somente isto não é suficiente, há pequenos detalhes que sempre atrapalham.
Neste artigo irei apresentar algumas boas práticas sobre a criação de usuários de banco de dados, a sintaxe do comando GRANT
e também alguns comandos prontos para criação de alguns tipos diferentes de usuários.
Normalmente o que se vê nos blogs, nos artigos, inclusive nos exemplos e em muitos paineis administrativos é a utilização de apenas uma combinação de usuário e senha para toda a aplicação. Um grande erro!
Os usuários MySQL além de terem o "nome de usuário" são associados ao endereço de origem, então você verá estes usuários normalmente no formato 'nomedeusuario'@'endereçodeorigem'
. Desta forma é possível que o usuário fulano tenha diferentes privilégios se estiver conectando no banco de dados através do endereço local (localhost
) ou a partir de uma máquina externa.
Na prática podemos considerar ambos os usuários diferentes, inclusive no momento da criação você não pode indicar apenas o endereço de origem ou o nome de usuário, é necessário indicar as duas informações sempre.
O símbolo %
é um caractere curinga que permite especificar parte de um endereço de origem ou até um usuário "que aceita todas as origens". Por exemplo o usuário 'fulano'@'192.168.0.%'
pode conectar através de qualquer máquina na rede 192.168.0.0/24
, o mesmo vale para nomes de máquinas desde que o servidor consiga resolver o nome do host de origem. O usuário 'fulano'@'%'
poderia conectar a partir de qualquer endereço, inclusive da mesma máquina.
Se sua aplicação está no mesmo servidor que o banco de dados, para sua segurança, você deve criar um usuário com host de origem localhost
para impedir que qualquer um que possuir o seu usuário e senha possa conectar de forma remota ao banco de dados.
Outra dica importante é sempre criar os usuários somente com os privilégios necessários, nada mais que isso. Não crie super usuários com privilégios de alterar a base e criar usuários a menos que sua aplicação necessite. Normalmente as aplicações apenas realizam consultas, inserções, atualizações e deleções, em alguns casos até evitando a última opção utilizando alguma técnica de softdelete. Tenha um usuário com muitos privilégios apenas para realizar as manutenções.
Observe que ao escrever o nome de usuário é conveniente envolver o nome de usuário e o endereço de origem com
'
. Eles devem ser envolvidos separadamente, o@
nunca deve estar dentro das aspas.
A sintaxe completa do statement GRANT
pode ser vista aqui. A sintaxe simplificada é:
GRANT <privilégios> ON <banco de dados>.<tabela> TO '<usuario>'@'<origem>' IDENTIFIED BY '<senha>';
A definição de senha por IDENTIFIED BY '<senha>'
é opcional, não sendo necessária se o usuário já existe.
Os privilégios, que podem ser definidos separados por vírgula no espaço indicado, são:
ALL
Equivalente ao conjunto de todos os privilégios abaixo, sem contar o privilégio de GRANT
ALTER
Permite alterar as tabelas e criar índices
ALTER ROUTINE
Permite alterar as stored procedures
CREATE ROUTINE
Permite criar novas stored procedures
EXECUTE
Permite executar stored procedures
CREATE
Permite criar tabelas e bancos de dados
CREATE TEMPORARY TABLES
Permite criar tabelas temporárias
CREATE USER
Permite criar, remover, alterar e inclusive remover os privilégios de usuários (não é possível conceder novos privilégios)
CREATE VIEW
Permite criar e alterar views
DELETE
Permite apagar linhas
DROP
Permite apagar views, tabelas, e bancos de dados
EVENT
Permite manipular os eventos
FILE
Permite com que o usuário crie e leia arquivos armazenados no servidor do banco de dados
GRANT OPTION
Permite remover e conceder privilégios aos usuários
INDEX
Permite criar ou apagar índices
INSERT
Permite inserir novas linhas no banco de dados
LOCK TABLES
Permite bloquear tabelas onde o usuário possui permissão de leitura
PROCESS
Concede permissões para ler a lista de processos executando no servidor
RELOAD
Permite a utilização de comandos FLUSH
SELECT
Concede permissão de leitura ao banco de dados ou tabelas
SHOW DATABASES
Permite ler a lista de bancos no servidor
SHOW VIEW
Permite ler a estrutura (query geradora) das views
SUPER
Concede poderes administrativos avançados
TRIGGER
Permite criar, alterar e apagar triggers
UPDATE
Permite a atualização de linhas no banco de dados
USAGE
É equivalente a nenhuma permissão
O comportamento e disponibilidade dos privilégios acima podem variar de acordo com a versão do MySQL. Eventos estão disponíveis apenas na versão 5.1 para cima, enquanto as triggers só podem ser editadas por usuários com super privilégios em versões inferiores a 5.0.
##Criando alguns usuários
Agora que já temos a sintaxe básica, vamos criar alguns usuários. No exemplo abaixo utilizarei além do GRANT
o statement CREATE USER
para criar os usuários. Isso deixa um pouco mais organizada a criação de usuários com privilégios diferentes em tabelas diferentes.
Para o exemplo abaixo pensamos na seguinte situação: criar o usuário DBA com permissões para realizar tudo em todas as tabelas do banco de dados, e dois usuários, FULANO com permissões para uma aplicação simples que está na mesma máquina e CICLANO que será utilizado para manutenção da base cujo FULANO irá ler as informações, chamada de BD01
. Para complicar um pouco a história, o CICLANO só poderá acessar esta base através de uma aplicação que está na máquina de IP 192.168.0.45
.
/* Criando o usuário DBA */
CREATE USER 'dba'@'%' IDENTIFIED BY 'senhaMuitoDificil';
GRANT ALL ON *.* TO 'dba'@'%' WITH GRANT OPTION;
/* Criando o usuário FULANO */
CREATE USER 'fulano'@'localhost' IDENTIFIED BY 'outraSenha';
GRANT SELECT,UPDATE,DELETE,INSERT ON BD01.* TO 'fulano'@'localhost';
/* Criando o usuário CICLANO */
CREATE USER 'ciclano'@'192.168.0.45' IDENTIFIED BY 'ehOutraSenha';
GRANT ALL ON BD01.* TO 'ciclano'@'192.168.0.45';
/* Recarregando as permissões na memória do servidor */
FLUSH PRIVILEGES;
Caso você altere as permissões de todos os usuários, inclusive do usuário ROOT e não consiga mais acessar o banco de dados, você pode iniciar o serviço com a opção
--skip-grant-tables
, conectar com qualquer usuário e senha e executarUPDATE mysql.user SET Password=PASSWORD('NovaSenhaAqui') WHERE User='root';
.
Note que com esta opção o serviço do MySQL vai ignorar qualquer privilégio e dará acesso total a todos que conectarem ao banco de dados, após trocar a senha reinicie o serviço sem o parâmetro o quanto antes por razões óbvias.
Note que o MySQL permite concedeer privilégios exclusivos a nível de coluna, porém quanto maior a quantidade de regras para definir privilégios maior o trabalho necessário para conferir se o usuário que está lendo a tabela possui permissões.