As long the internal functions are called inside all the public method then it is okay and it is better to add the modifier to the internal function.

The easiest one is the following from the openzeppelin Wizard
(https://docs.openzeppelin.com/contracts/4.x/wizard)

 

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;
    
    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
    import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
    import "@openzeppelin/contracts/security/Pausable.sol";
    import "@openzeppelin/contracts/access/Ownable.sol";
    
    contract MyToken is ERC20, ERC20Burnable, Pausable, Ownable {
        constructor() ERC20("MyToken", "MTK") {}
    
        function pause() public onlyOwner {
            _pause();
        }
    
        function unpause() public onlyOwner {
            _unpause();
        }
    
        function _beforeTokenTransfer(address from, address to, uint256 amount)
            internal
            whenNotPaused
            override
        {
            super._beforeTokenTransfer(from, to, amount);
        }
    }